1 构建SourceNode

来源:互联网 发布:和彩云是什么软件 编辑:程序博客网 时间:2024/06/05 06:19

part 1:

在媒体文件格式被识别后就要根据文件格式创建节点,调用函数DoSetupSourceNode

PVPlayerEngine::DoSetupSourceNode(PVCommandId aCmdId, OsclAny* aCmdContext)

参数:

aCmdId:命令ID;

aCmdContext:

在实际的调用中,这两个参数分别是类PVPlayerEngineContext成员量

函数返回值:函数执行状态,成功与否;

本函数的作用就是根据源文件格式和输出格式,在注册的节点中查找相符合的,并创建源节点

1)调用函数PVPlayerNodeRegistry::QueryRegistry(PVMFFormatType& aInputType, PVMFFormatType& aOutputType, Oscl_Vector<PVUuid, OsclMemAllocator>& aUuids)

参数分别是源文件格式(输入格式),输出文件格式,保存UUID的vector量;根据输入、输出格式对,查找合适的Node并保存其UUID

2)调用函数PVPlayerNodeRegistry::CreateNode(PVUuid& aUuid)根据上面查到的UUID创建Node,函数返回指向类PVMFNodeInterface的指针;

3)将UUID和Node指针保存到结构体PVPlayerEngineUuidNodeMapping中,并存放到vector量iNodeUuids中;

4)构造类PVMFNodeSessionInfo,保存于Node有关的信息

5)调用函数PVMFNodeInterfaceImpl::Connect(const PVMFNodeSessionInfo &aSession),函数的参数就是上面构建的节点信息类,函数返回sessionID;此函数将aSession以及sessionID保存到一个指向类PVMFNodeSession指针变量中,并存储到类PVMFNodeInterface的成员vector量iSessions指向的内存中;

6)调用函数

PVMFCommandId PVMFNodeInterfaceImpl::QueryInterface(PVMFSessionId aSessionId,
        const PVUuid& aUuid,
        PVInterface*& aInterfacePtr,
        const OsclAny* aContext)

参数:

aSessionId:上面提到的ID;

aUuid:PVMF_DATA_SOURCE_INIT_INTERFACE_UUID;

aInterfacePtr:输出参数,目前为NULL;

aContext:指向类PVPlayerEngineContext,调用函数AllocateEngineContext构建,

AllocateEngineContext(NULL, iSourceNode, NULL, aCmdId, aCmdContext, PVP_CMD_SourceNodeQueryInitIF);

7)QueryInterface函数的构建一个cmd(PVMFNodeCommand),并将此命令添加到命令队列中进行处理;

调用函数cmd.PVMFNodeCommandBase::Construct(PVMFSessionId s, int32 aCmd, const PVUuid& aUuid,
                                                                              PVInterface*& aInterfacePtr,
                                                                                const OsclAny* aContext)

参数:

s:输入参数,同QueryInterface;

aCmd:输入参数,命令ID,PVMF_GENERIC_NODE_QUERYINTERFACE,指明此命令是查询接口;

aUuid、aInterfacePtr、aContext:输入参数,同QueryInterface;

此函数构建命令类型CMD,在构建时,

iParam1 = uuid.ALLOC_AND_CONSTRUCT(aUuid);
iParam2 = (OsclAny*) & aInterfacePtr;

Node命令类PVMFNodeCommand继承类PVMFNodeCommandBase;

顺便分析下函数AllocateEngineContext

PVPlayerEngine::AllocateEngineContext(PVPlayerEngineDatapath* aEngineDatapath, PVMFNodeInterface* aNode, PVPlayerDatapath* aDatapath, PVCommandId aCmdId, OsclAny* aCmdContext, int32 aCmdType)

参数:

aNode:Node接口指针;

aCmdId,aCmdContext:与函数DoSetupSourceNode参数相同;

aCmdType:命令类型;

函数返回指向类PVPlayerEngineContext的指针;

此函数功能就是构建了一个PVPlayerEngineContext,并将函数传递过来的参数保存,最后将此context加入到vector量iCurrentContextList中;

part 2:

在将命令加入到命令队列后,接下是处理,在其他的类中队命令的处理时调用类中成员函数Run(),但是在类PVMFNodeInterfaceImpl中却是调用其成员函数ProcessCommand()

1)首先会处理优先级较高的命令,如取消命令等;

2)再会处理正常普通命令;

3)在此进入函数DoQueryInterface(),是类PVMFNodeInterfaceImpl的成员函数,不过是虚函数,实际调用的是函数:

PVMFMP3FFParserNode::DoQueryInterface(),其中类PVMFMP3FFParserNode是MP3文件的解析Nodel类,类PVMFNodeInterfaceImpl是其众多父类中的一个,有如下继承关系:

22

4)函数返回,调用函数PVMFNodeInterfaceImpl::CommandComplete(iCurrentCommand, status, NULL, eventData),通知函数完成,

函数PVMFNodeInterfaceImpl::CommandComplete(PVMFNodeCommand& aCmd, PVMFStatus aStatus,
        PVInterface* aExtMsg, OsclAny* aEventData, PVUuid* aEventUUID, int32* aEventCode, int32 aEventDataLen)

参数:

aCmd:当前命令指针;aStatus:命令执行后的返回结果;

函数PVMFMP3FFParserNode::DoQueryInterface()

1)首先根据当前命令量调用函数PVMFNodeCommandBase::Parse(PVUuid*&aUuid, PVInterface**&aInterface),此函数仅是将前面保存的参数提取出来;

2)调用函数queryInterface(*uuid, *ptr)

PVMFMP3FFParserNode::queryInterface(const PVUuid& uuid, PVInterface*& iface)

参数:

uuid:输入参数,用于判断构造哪个接口指针;

iface:输出参数,指向构建的类;

此处UUID为PVMF_DATA_SOURCE_INIT_INTERFACE_UUID,构建指针指向类PVMFDataSourceInitializationExtensionInterface,但是在返回之前将其转化为PVInterface*类型,保存此指针在参数*ptr中;

3)函数返回;

PVMFCmdResp resp(aCmd.iId, aCmd.iContext, aStatus, extif, aEventData);