Android的多媒体框架Opencore代码阅读

目录结构

OpenCore的代码在以下目录中:external/opencore/。这个目录是OpenCore的根目录,其中包含的子目录如下所示:

* android:这里面是一个上层的库,它基于PVPlayer和PVAuthor的SDK实现了一个为Android使用的Player和Author。(android_audio_input/output/steam.cpp)

* baselibs:包含数据结构和线程安全等内容的底层库
* codecs_v2:这是一个内容较多的库,主要包含编解码的实现,以及一个OpenMAX的实现

(OpenMAX是一个多媒体应用程序的标准。由NVIDIA公司和Khronos™在2006年推出。

OpenMAX是Khronos制定的API,这个Khronos也是OpenGL的制定者,同时在着手制定的标准/规范还有OpenGL es,OpenVG,OpenEL等等,其中大多都是针对手持设备/嵌入式设备的。

OpenMAX的作用

1.加速跨OS和silicon平台的多媒体组建的开发、整合和编程;

2.使library和codec实现者能够快速有效的利用新silicon的潜在的加速功能,而不关心下层的硬件结构。

OpenMAX的层次

OpenMAX自上而下分为三个层次:OpenMAX AL,OpenMAX IL和OpenMAX DL。

OpenMAX AL:Application Layer, 应用和多媒体中间层的标准接口,使得应用在多媒体接口上具有了可移植性

OpenMAX IL: Integrateion Layer,作为在嵌入式和移动设备中使用的audio,video,images codecs的底层接口。使得AP和多媒体框架可以以统一的方式访问多媒体codec和支持组件。Codec可以是硬件和软件的任意组合,对用户透明。

OpenMAX DL: Development Layer 定义了一套API,包含了audio,video和imaging使用的函数集合,这些函数可以由芯片厂商针对新的处理器进行实现和优化,然后被codec 厂商在各种codec上使用。)

* 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等文件。
我们由底往上看,pvwavfileparser.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)

更多相关文章

  1. C语言函数以及函数的使用
  2. Android 4.1源码编译找不到资源文件解决办法
  3. 我的第一个Android 多媒体的Demo
  4. Android 根文件系统分析
  5. Android中的AndroidManifest.xml文件
  6. android中的资源,资源与xml文件

随机推荐

  1. 基于ffmpeg的Android播放器开源代码
  2. android图片轮播+点击跳转广告页面
  3. android 按键
  4. 2011.06.29(2)——— android 完全退出
  5. Android(安卓)ContentProvider的介绍
  6. 小米,红米手机android 6.0以下 权限管理
  7. 《Android(安卓)Studio 问题解决集锦》
  8. 林志华_Android
  9. cmake 编译 ogre3D(version1.9) for androi
  10. 【Android學習專題】實用參考:android权限