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是其众多父类中的一个,有如下继承关系:
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);