引用:http://blog.csdn.net/wstarx/archive/2008/12/17/3541458.aspx

目录结构 OpenCore的代码在以下目录中:external/opencore/。这个目录是OpenCore的根目录,其中包含的子目录如下所示: * android:这里面是一个上层的库,它基于PVPlayer和PVAuthor的SDK实现了一个为Android使用的Player和Author。 * baselibs:包含数据结构和线程安全等内容的底层库 * codecs_v2:这是一个内容较多的库,主要包含编解码的实现,以及一个OpenMAX的实现 * engines:包含PVPlayer和PVAuthor引擎的实现 * extern_libs_v2:包含了khronos的OpenMAX的头文件 * fileformats:文件格式的据具体解析(parser)类 * nodes:编解码和文件解析的各个node类。 * oscl:操作系统兼容库 * pvmi: 输入输出控制的抽象接口 * protocols:主要是与网络相关的RTSP、RTP、HTTP等协议的相关内容 * pvcommon:pvcommon库文件的Android.mk文件,没有源文件。 * pvplayer:pvplayer库文件的Android.mk文件,没有源文件。 * pvauthor:pvauthor库文件的Android.mk文件,没有源文件。 * tools_v2:编译工具以及一些可注册的模块。 Splitter的定义与初始化 以wav的splitter为例,在fileformats目录下有解析wav文件格式的pvwavfileparser.cpp文件,在nodes目录 下有pvmf_wavffparser_factory.cpp,pvmf_wavffparser_node.h, pvmf_wavffparser_port.h等文件。 我们由底往上看,vwavfileparser.cpp中的PV_Wav_Parser类有InitWavParser(),GetPCMData(),RetrieveFileInfo()等解析wav格式的成员函数,此类应该就是最终的解析类。我们搜索PV_Wav_Parser类被用到的地方可知,在PVMFWAVFFParserNode类中有PV_Wav_Parser的一个指针成员变量。再搜索可知,PVMFWAVFFParserNode类是通过PVMFWAVFFParserNodeFactory的CreatePVMFWAVFFParserNode()成员函数生成的。而CreatePVMFWAVFFParserNode()函数是在PVPlayerNodeRegistry::PVPlayerNodeRegistry()类构造函数中通过PVPlayerNodeInfo类被注册到Oscl_Vector 的vector中,在这个构造函数中,AMR,mp3等node也是同样被注册的。 由上可知,Opencore中对splitter的管理也是与ffmpeg等类似,都是在框架的初始化时注册的,只不过Opencore注册的是每个splitter的factory函数。 综述一下splitter的定义与初始化过程: 每个splitter都在fileformats目录下有个对应的子目录,其下有各自的解析类。 每个splitter都在nodes目录下有关对应的子目录,其下有各自的统一接口的node类和node factory类。 播放引擎PVPlayerEngine类中有PVPlayerNodeRegistry iPlayerNodeRegistry成员变量。 在PVPlayerNodeRegistry的构造函数中,将 AMR, AAC, MP3等splitter的输入与输出类型标示和node factory类中的create node与release delete接口通过PVPlayerNodeInfo类push到Oscl_Vector iType成员变量中。 当前Splitter的匹配过程 PVMFStatus PVPlayerNodeRegistry::QueryRegistry(PVMFFormatType& aInputType, PVMFFormatType& aOutputType, Oscl_Vector& aUuids)函数的功能是根据输入类型和输出类型,在已注册的node vector中寻找是否有匹配的node,有的话传回其唯一识别标识PVUuid。 从QueryRegistry这个函数至底向上搜索可得到,在android中splitter的匹配过程如下: android_media_MediaPlayer.cpp之中定义了一个JNINativeMethod(JAVA本地调用方法)类型的数组gMethods,供java代码中调用MultiPlayer类的setDataSource成员函数时找到对应的c++函数 {"setDataSource", "(Ljava/lang/String;)V", (void *)android_media_MediaPlayer_setDataSource}, static void android_media_MediaPlayer_setDataSource(JNIEnv *env, jobject thiz, jstring path) 此函数中先得到当前的MediaPlayer实例,然后调用其setDataSource函数,传入路径 status_t MediaPlayer::setDataSource(const char *url) 此函数通过调getMediaPlayerService()先得到当前的MediaPlayerService, const sp& service(getMediaPlayerService()); 然后新建一个IMediaPlayer变量, sp player(service->create(getpid(), this, fd, offset, length)); 在sp MediaPlayerService::create(pid_t pid, const sp& client, const char* url)中 调status_t MediaPlayerService::Client::setDataSource(const char *url)函数,Client是MediaPlayerService的一个内部类。 在MediaPlayerService::Client::setDataSource中,调sp MediaPlayerService::Client::createPlayer(player_type playerType) 生成一个继承自MediaPlayerBase的PVPlayer实例, PVPlayer的继承关系如下: PVPlayer-->MediaPlayerInterface-->MediaPlayerBase 最后调PVPlayer的setDataSource()函数 status_t PVPlayer::setDataSource(const char *url) status_t PVPlayer::prepare() 此函数开头执行ret = mPlayerDriver->enqueueCommand(new PlayerSetDataSource(mDataSourcePath,0,0)); 将PlayerSetDataSource 的command类加入到PlayerDriver的command处理队列中, 在void PlayerDriver::Run()函数中处理此command,调用下面的handleSetDataSource函数。 void PlayerDriver::handleSetDataSource(PlayerSetDataSource* ec) PVCommandId PVPlayerEngine::AddDataSource(PVPlayerDataSource& aDataSource, const OsclAny* aContextData) This function allows a player data source to be specified for playback. This function must be called PVMFStatus PVPlayerEngine::DoAddDataSource(PVPlayerEngineCommand& aCmd) PVMFStatus PVPlayerEngine::DoSetupSourceNode(PVCommandId aCmdId, OsclAny* aCmdContext) 

 

以上,是前辈摸索出的一条线索,但是不全面,至少对我现在的工作来说如此.

其以WAV格式为突破口,止步于CreatePVMFWAVFFParserNode().最后这段代码位置是在 external/opencore/engines/player/config/linux_nj/pv_player_node_registry.cpp中.

 

我们已经知道3gp格式是支持的,但是android代码中并没有明确的有关3gp的文件解析node或者代码,在PVPlayer的方法中enqueueCommand(),再在playerdriver的Run()中,dequeueCommand()并且根据command->code(),做相应的操作.

其中就有handleSetDataSource(),这个方法看上去与文件格式解析相关.

 

handleSetDataSource()中会调用pv_player_engine.cpp中的AddDataSource()方法,发出一个Command:“PVP_ENGINE_COMMAND_ADD_DATA_SOURCE”到队列中,

接着在Run()中的switch(...)语句中,执行DoAddDataSource(),在这里

if(iSourceFormat=SOURCEFORMAT_UNKNOWN)

{

     retval = DoQuerySourceFormat(...);

}

else

{

      ...

}

 

DoQuerySourceFormat()中,参数iPlayerRecognizerRegistry闪亮登场,其类型为PVPlayerRecognizerRegistry,通过

iPlayerRecognizerRegistry.QueryFormatType(iDataSource->GetDataSourceURL(), *this, (OsclAny*) context));

在QueryFormatType()中,会使用传入的文件路径创建一个PVMIDataStreamSyncInterfaceRefFactory对象,并强制转换成PVMFDataStreamFactory*.再使用PVMFRecognizerRegistry::Recognize(iRecSessionId, *iFileDataStreamFactory, NULL, iRecognizerResult, NULL);它会继续向下调用PVMFRecognizerRegistryImpl::Recognize(...),将参数保存,再生成一个CMD:PVMFRECREG_COMMAND_RECOGNIZE,再在PVMFRecognizerRegistryImpl::Run()中,通过switch(...)执行doRecognize().

 

可以理解为所有解析的node都保存在iRecognizerPluginFactoryList中,再在doRecognaize()中遍历,以获得合适的node(I am not sure!XD)

 

 

以下可以忽略

/*******************************************************************************************

初始化位置是在PVPlayerEngine::PopulateRecognizerRegistry(...)中,这个函数是被PopulateAllRegistries(...)调用,而PopulateAllRegistries(...)在PlayerEngine的Construct()中调用,并且其在调用PopulateRecognizerRegistry(...)之前,还会调用一个PopulateNodeRegistry(...),暂且把PopulateAllRegistries(...)放下不谈,回到PopulateRecognizerRegistry(...)中,首先通过读取config文件(/system/etc/pvplayer.conf),将其中与PV_RECOGNIZER_INTERFACE相同Uuid的动态库加载进来...(这里为什么会指定一个Uuid呢?这个Uuid在config文件中对应的正是 libopencoremp4reg.so,也就是说,格式为UNKNOWN的,都用这个库来识别?...继续看). 这个库本身就是opencore的一个node,生成它的Android.mk位于"external/opencore/tools_v2/build/modules/linux_mp4/node_registry",可以看出,他其实就是nodes/pvmp4ffparsernode,到此,文件解析的动态库也已加载.明天来继续往下看,今天再温习一下流程,思索下...

*********************************************************************************************/

 

 

好吧,其实android 1.5不支持.MP4的现象是因为我的.mp4文件的声音部分是用的aac编码,而android本身只支持wav的音频编码...so,虽然能够识别出是video/mp4,但是却会导致播放器die(因为我的播放器没做纠错)

 

更多相关文章

  1. 使用SAX或者DOM或者pull解析XML文件
  2. Android 依赖注入函数库Roboguice(一)
  3. Android读取文件方法总结
  4. Android使用PULL解析和生成XML文件
  5. android中svg文件的使用
  6. android资源文件之:shape详解
  7. Android 通过命令将文件导出
  8. Android开发8――利用pull解析器读写XML文件

随机推荐

  1. Android传感器(五):线性加速度传感器
  2. Android中常用的bitmap处理方法
  3. 7.1.3 TimePicker结合案例详解
  4. Android用户和用户组的定义
  5. Android 源码下载遇到 403错误 的解决办
  6. Android判断程序是否第一次启动
  7. Android XMPP 即时通讯
  8. Android裁剪图像实现方法示例
  9. Android自动测试代码
  10. 关于android软键盘隐藏总结