在完成文件解析后就要添加输出sink了,在这里,以AudioSink为例来进行说明,关于Video的设置,请参考《OpenCore视频硬件加速》。
首先在Driver层介绍上层命令(PlayerSetAudioSink*)处理:
函数PlayerDriver::handleSetAudioSink(PlayerSetAudioSink* command)
1)构建指向类AndroidAudioOutput的指针,保存在Driver的成员mAudioOutputMIO中,有关此类的描述:音频buffer会在一个独立的音频输出线程中加入到一个消息队列中,一旦数据buffer成功写入,就会通过另一个消息队列返回到MIO和Engine中去。
2)调用mAudioOutputMIO->setAudioSink(command->audioSink()),参数是command中的audiosink,将参数传送到mAudioOutputMIO的成员mAudioSink中去,mAudioSink的类型是sp<MediaPlayerInterface::AudioSink>
3)PVMediaOutputNodeFactory::CreateMediaOutputNode(mAudioOutputMIO),创建输出Node,返回指向类PVMediaOutputNode的指针,保存在mAudioNode(PVMFNodeInterface*)中,类PVMFNodeInterface是类PVMediaOutputNode的父类;
继承关系:
class PVMediaOutputNode
: public PVMFNodeInterfaceImpl
: public PVMFNodeInterface
: public PVMFPortActivityHandler
, public PvmiMIOObserver
, public PvmfNodesSyncControlInterface
, public PvmiCapabilityAndConfigBase
4)构建类PVPlayerDataSinkPVMFNode,指针mAudioSink(PVPlayerDataSink*),类PVPlayerDataSink是类PVPlayerDataSinkPVMFNode的父类;在此要注意mAudioNode与mAudioSink的不同,两者没有类的继承关系;
5)((PVPlayerDataSinkPVMFNode *)mAudioSink)->SetDataSinkNode(mAudioNode),体现出了PVPlayerDataSinkPVMFNode与PVMediaOutputNode的关系,将指向PVMediaOutputNode的指针传递给类PVPlayerDataSinkPVMFNode的成员iNode;
6)mPlayer->AddDataSink(*mAudioSink, command),进入Engine层处理;
函数PVPlayerEngine::AddDataSink(PVPlayerDataSink& aDataSink, const OsclAny* aContextData)
调用函数AddCommandToQueue(PVP_ENGINE_COMMAND_ADD_DATA_SINK, (OsclAny*)aContextData, ¶mvec)新建命令并添加到命令队列,将aDataSink保存在param.pOsclAny_value中;
关于cmd:
命令类型,cmdID,aContextData,aParamVector,就是这几个量。
函数PVPlayerEngine::DoAddDataSink(PVPlayerEngineCommand& aCmd)
参数:cmd就是上面刚添加到命令队列中的命令。
1)从命令中取出datasink(PVPlayerDataSink*);
2)再将datasink保存在newdatapath(PVPlayerEngineDatapath).iDataSink中,
3)将newdatapath加入到iDatapathList(路径列表),iDatapathList是类PVPlayerEngine的一个成员量;
4)EngineCommandCompleted函数完成;