类PVPlayerDatapath中包含成员量指向SourceNode,DecNode,SinkNode,以及SessionID,还有四个port指针:
PVMFPortInterface* iSourceOutPort;
PVMFPortInterface* iDecInPort;
PVMFPortInterface* iDecOutPort;
PVMFPortInterface* iSinkInPort;
在Engine层完成Doprepare命令后,就会进入Datapath部分
函数PVPlayerEngine::DoDatapathPrepare
1)对参数aDatapath进行设置,主要是关于SinkNode和DecNode,其中涉及到observer的都是Engine
2)构建context,调用函数PVPlayerDatapath::Prepare(OsclAny* aContext);
函数PVPlayerDatapath::Prepare(OsclAny* aContext)
1)设置iDatapathConfig为CONFIG_DEC;
2)新建sessioninfo(PVMFNodeSessionInfo)作为中间量,将有关SourceNode和SinkNode、DecNode的info加入到iSessions中(是nodeInterface的成员)
调用的是函数connect(const PVMFNodeSessionInfo &aSession),此函数读取将包含Node信息的参数添加到iSessions中,并返回session的ID;
3)设置状态为PREPARE_INIT,调用函数RunIfNotReady();
函数PVPlayerDatapath::Run()
1)根据状态类型分情况处理
2)若iState值为PREPARE_INIT,调用函数IssueDatapathInit(iDecNode, iDecSessionId, cmdid),从参数可以看出首先是对DecNode进行初始化,接下来对SinkNode进行初始化;
3)若iState值为PREPARE_REQPORT,调用函数IssueDatapathRequestPort,查询port函数
首先是查询SourceNode的port,再是DecNode的Input port,接着是DecNode的Output,最后是SinkNode
port接口类:class PVMFPortInterface
成员量:PVMFPortInterface* iConnectedPort;指向与当前port链接的port的指针;
PVMFPortActivityHandler *iPortActivityHandler;
SourceNode中查询port:
PVMFNodeInterfaceImpl::ProcessCommand()
--PVMFMP3FFParserNode::DoRequestPort(PVMFPortInterface*&aPort)
porttag==PVMF_MP3FFPARSER_NODE_PORT_TYPE_SOURCE这是SourceNode所支持的portType
根据tag,构建PVMFMP3FFParserPort类型,port类继承关系如下图示
构建完成后对MP3FFparserNode的成员量iTrack(PVMP3FFNodeTrackPortInfo) 进行填充,保存port的info;
构建port完成后返回到PVPlayerDatapath层,将获得port指针保存到datapath层iSourceOutPort中;
接下来同样是获取剩下的port;
DecNode中查询输入port:
--PVMFOMXBaseDecNode::Run()
--PVMFNodeInterfaceImpl::ProcessCommand()
--PVMFOMXAudioDecNode::DoRequestPort(PVMFPortInterface*& aPort)
--根据tag类型构建类型为PVMFOMXDecPort的量iInPort,最后将这个port指针传递给datapath的成员量iDecInPort中;
DecNode类的继承关系:
类PVMFOMXDecPort的继承关系:
SinkNode中查询port:
在调用处理函数是,进入PVMediaOutputNode层;
——PVMFNodeInterfaceImpl::ProcessCommand()
——PVMediaOutputNode::DoRequestPort(PVMFPortInterface*& aPort)
又回到PVMediaOutputNode,构建的port的类型是PVMediaOutputNodePort
类PVMediaOutputNode的继承关系如下图示:
在构建sinkNode的por指针是就没有想前面的那样仅是调用构造函数那么简单,而是在构建对象后,有做了一些设置;在类PVMediaOutputNode中有个成员iInPortVector,是vector量,在构造port后将port指针加入到这个vector中;
PVMediaOutputNode::DoRequestPort(PVMFPortInterface*& aPort)
——构建port
——PVMediaOutputNodePort::Configure(OSCL_String& fmtstr):配置port的格式,
——PVMediaOutputNode::SetClock(PVMFMediaClock* aClock):设置时钟;
DecNode中查询输出port:
与输入唯一不同的就是porttag不同;
此时所有的RequestPort()完成,返回到datapath中,执行PREPARE_CONNECT部分。
datapath中的Run()函数:
根据iState的值,PREPARE_CONNECT来处理:
1)源输出port和DecINport分别查询接口,源输出port调用connect(iDecInPortv),实现连接;
2)DecOutport和Sinkinport查询接口,DecOutport接口调用connect,实现连接;
函数PvmfPortBaseImpl::Connect(PVMFPortInterface* aPort)
1)根据参数aPort调用PeerConnect(this),
2)将iConnectedPort设置为aPort;
其实函数PeerConnect也是将iConnectedPort设置一下,实现我中有你,你中有我;
Run()函数处理PREPARE_PREPARE部分
1)sinkNode执行Prepare,再对DecNode执行Prepare;
DecNode的Prepare:
——PVMFOMXBaseDecNode::Run()
——PVMFNodeInterfaceImpl::ProcessCommand()
——PVMFOMXBaseDecNode::DoPrepare()
——从输入port获得文件格式并保存
——OMX_MasterGetComponentsOfRole,查询支持此role的组件,并列表;
获得支持此格式的组件后,就要对其实例化并与之协商,如果有多个组件支持此role和格式,则基于track selection helper提供的组件顺序list选择组件,如果没有使用track selection helper,则通过组件在OMX_MasterInit时注册的顺序选择;一个组件不行,则使用下一个直至一个能用;
——OMX_MasterConfigParser;
——OMX_MasterGetHandle,根据组件名创建组件,指针保存在iOMXDecoder中,在此会加载libomx_mp3dec_sharedlibrary.so库,构建MP3解码组件,
——PVMFOMXBaseDecNode::CheckComponentForMultRoles(OMX_STRING aCompName, OMX_STRING aRole),检查组件是否支持多个role
——PVMFOMXBaseDecNode::CheckComponentCapabilities(PVMFFormatType* aFormat, OMX_PTR aOutputParameters),对解码组件的指示功能的参数设置(true或FALSE);
——PVMFOMXAudioDecNode::NegotiateComponentParameters(OMX_PTR aOutputParameters)
从这能看出,DecNode和components的关系