PlayerDriver类就是PVPlaer类的员工,PVPlayer就是PlayerDriver的老板,PVPlayer要干什么事情根本不用自己操心,它就向PlayerDriver的工作表上发送一个一个的条目就行了,然后它就打球唱歌逍遥去了。然后听取一下PlayerDriver的工作成果就ok了。
哎,我啥时候才能做到PVPlayer的那种程度啊...
废话不多说了,该干的还是得干,谁叫咱只是个PlayerDriver呢。
首先看看PlayerDriver类的声明:
这说明了什么?答案是:这说明了PlayerDriver要干的事情还真不少(这不是废话么)。
让我们逐个说明PlayerDriver的基类是干嘛的:
public OsclActiveObject:这个类的声明在文件external/opencore/oscl/oscl/osclproc/src/oscl_scheduler_ao.h,它说明PlayerDriver类的可以被加入到scheduler中执行...(这又是什么意思?)解释起来太费事,容我稍后单独在一个章节中说明(先占位,以后给出链接)。
public PVCommandStatusObserver:
public PVInformationalEventObserver:
public PVErrorEventObserver:这三个类的声明在文件external/opencore/engines/common/include|pv_engine_observer.h中,它说明原来PlayerDriver是某个类的的观察者(原来PlayerDriver也是个小boss,可以像手下发布命令)。
PlayerDriver的重要的成员变量如下:
PVPlayer *mPvPlayer; //这是PlayerDriver的老板,给他发命令的家伙
PVPlayerInterface *mPlayer; //这是PlayerDriver的手下,完成大部分的工作
PVPlayerDataSourceURL *mDataSource; //如变量名所言:datasource
PVPlayerDataSink *mAudioSink; //如变量名所言:datasink
PVMFNodeInterface *mAudioNode;
AndroidAudioMIO *mAudioOutputMIO;
PVPlayerDataSink *mVideoSink;
PVMFNodeInterface *mVideoNode;
AndroidSurfaceOutput *mVideoOutputMIO;
PvmiCapabilityAndConfig *mPlayerCapConfig;
PlayerDriver的构造函数和大多数类的构造函数一样,都是吧类的内存分配时往变量里分配的随机值改变成默认的0,以及创建一些公用的锁之类,但是其中要提到的是这一行:
createThreadEtc(PlayerDriver::startPlayerThread, this, "PV player");
createThreadEtc的声明在文件frameworks/base/include/utils/threads.h中,而它的实现在文件frameworks/base/libs/utils/Threads.cpp,它干的事情很简单,就是创建一个线程。
顺便说几句,opencore内部定义的oscl层就是用来进行threads,IO,memory等操作系统相关的操作的定义,它为什么要引用android的内容呢?我的理解是:opencore也有它不完善的地方,或者说我所工作的这个版本的opencore是在android分支下,它本来就和android绑定的比较紧。
这个线程最终调用到int PlayerDriver::playerThread()。
这个函数得仔细解释了,因为它的是整个PlayerDriver的工作线程,也就是执行命令,干活的那个线程。
OMX_MasterInit(); 初始化OpenMax 的主核心(Master Core),而这个主核心管理着若干从核心(Slave Core),每个从核心都可以是一个单独的OpenMax IL的实现,他们通过动态加载的方式被主核心加载进来,然后若干个实现并存于Opencore中,向上层提供codec层的接口。
OsclScheduler::Init("AndroidPVWrapper"); 初始化一个调度器,用来提供给PlayerDriver使用。这个调度器的工作线程就是当前线程,也即所有调度器中运行的内容都要通过这个调度器在这个线程内完成。
OSCL_TRY(error, mPlayer = PVPlayerFactory::CreatePlayer(this, this, this)); 创建一个PVPlayerInterface类,在这里,它创建一个PVPlayerEngine的实例。这个类才是实际干活的,PlayerDriver只是一个传话的,最后的工作教导PVPlayerEngine中。
AddToScheduler(); 将自身(this)添加到调度器。
PendForExec(); 阻塞调度器。
OSCL_TRY(error, sched->StartScheduler(mSyncSem)); 开始干活喽。
剩下这些代码,不用解释就知道干嘛的了:
删除那些通过命令的中间过程而申请的资源,或者说创建的对象。
PVPlayer通过调用PlayerDriver::enqueueCommand来传递命令给PlayerDriver。
PlayerDriver则通过PlayerDriver::handleXXXXXXXXX来处理各个命令。
PlayerDriver能通过吧PVPlayer调用传递过来的参数转换成PVPlayerInterface能识别的参数,再传递给PlayerDriver:mPlayer来完成各个命令。