您的位置:华清远见教育科技集团 >> Android资料 >> OpenCORE文件解析和组合处理  
 
OpenCORE文件解析和组合处理
分享到:

由于同时涉及播放文件和记录文件两种功能,因此OpenCORE中的文件格式处理有两种类型。一种是解析器(Parser),用于解析文件;另一种是组合器(Composer),用于记录文件。

在媒体文件的播放过程中,一个视频文件会包含音频流和视频流的组合,如在一个MP4文件中,可能包含了AMR或AAC的音频压缩流,以及H263、MPEG 4或者H264 AVC的视频压缩流。这些流文件被封装在一个包文件中,媒体播放器首先要做的就是将这些流文件从包文件中解析出来,然后根据文件类型的不同调用不同的解码器进行解码,后将解码后的元数据流输送到相应的硬件设备进行播放。

在媒体文件的记录过程中,涉及视频、音频、图像的捕获功能。如在录像过程中,首先需要从硬件设备分别获得视频元数据流和音频元数据流,然后根据相关的配置信息,将元数据流压缩成相应格式的压缩流,并写入文件中,终组合成相应的包文件。

需要说明的是,目前中、高端的移动终端上都配备了专门用于多媒体加速的DSP,相关的音频、视频编解码工作都会在专用DSP上进行。OpenCORE关于文件格式解析的内容位于external\opencore\fileformats和external\opencore\protocols\sdp\parser目录下。

下面分别以MP3和MPEG-4为例来分析解析器、组合器的实现。

1.解析器

在Android中,目前内置了AVI、MPEG-4、WAV、MP3、AMR、AAC等格式的解析器。下面以MP3为例介绍解析器的实现,相关的文件包括imp3ff.cpp、mp3fileio.cpp、mp3parser.cpp、mp3utils.cpp等。具体实现位于external\opencore\fileformats\ mp3\parser目录下。

在Android中,MP3解析器节点的注册是在PVMERegistryPopulator::RegisterAllNodes()方法中完成的。

为了进行MP3文件的播放,需要将MP3的数据源添加到播放引擎中,在添加数据源的过程中会进行文件解析。MP3播放时进行文件解析的过程如下图所示。

MP3播放时的文件解析过程
MP3播放时的文件解析过程

流程说明:

在客户端通过PlayerDriver添加数据源的过程中,PVPlayerEngine引擎会向一个线程安全的事件队列iThreadSafeQueue中添加PVP_ENGINE_COMMAND_ADD_ DATA_SOURCE命令。当PVPlayerEngine引擎收到该命令后,调用DoAddDataSource()方法进行数据源的添加。

根据传过来的命令ID,PVPlayerEngine引擎获得当前的PVPlayerDataSource对象,然后调用PVPlayerDataSource::GetDataSourceFormatType()方法查看当前的文件格式。如果文件格式未知,就需要根据传递的命令ID和命令上下文调用DoQuerySourceFormatType()方法进行文件格式的解析了。

在DoQuerySourceFormatType()方法中,会经过一系列的操作获得一个PVMFCPMPluginAccessInterfaceFactory对象,然后根据该对象调用PVPlayer RecognizerRegistry:: QueryFormatType()方法打开识别器(Recognizer)的会话并进行识别。

PVMFRecognizerRegistry对象通过调用PVMFRecognizerRegistryImpl::Recognize()方法,向自身发送一个PVMFRECREG_COMMAND_RECOGNIZE命令,将工作交给PVMF RecognizerRegistryImpl::DoRecognize()方法进行接下来的处理。

在PVMFRecognizerRegistryImpl::DoRecognize()方法中,首先会通过CheckFor DataAvailability()方法验证数据的有效性,然后通过RunRecognitionPass()方法调用解析器插件。直到这时,PVMP3FFRecognizerPlugin才有了用武之地。

在PVMP3FFRecognizerPlugin::Recognize()方法中,会首先通过OSCL_NEW()方法创建一个IMpeg3File对象。然后调用IMpeg3File::IsMp3File()方法判断该文件是不是MP3文件。

在IMpeg3File::IsMp3File()方法中,会通过OSCL_NEW()方法创建一个MP3Parser对象,然后在MP3Utils和MP3FileIO的配合下,通过MP3Parser::GetMP3Header()尝试获得MP3的头文件。如果成功,再通过MP3Parser::DecodeMP3Header()来解析该头文件,通过同样成功,则确认该文件就是MP3文件了。

在完成了文件的解析后,即开始解码工作,关于MP3的解码工作请参考6.2.3节MP3的解码过程。

2.组合器

在Android中,目前内置了MPEG-4等格式的组合器,组合器的实现要比解析器复杂的多。下面以MPEG-4为例介绍组合器的实现,相关的文件位于external\了opencore\fileformats\mp4\composer目录下。下图所示为MP4记录时的文件解析过程。

MP4记录时的文件解析过程
MP4记录时的文件解析过程

流程说明:

在进行MP4记录时,客户端会通过PVMediaRecorder::setOutputFormat()方法向记录引擎PVAuthorEngine发送AUTHOR_SET_OUTPUT_FORMAT消息,设置输出文件的格式。

在AuthorDriver的监听线程收到AUTHOR_SET_OUTPUT_FORMAT消息后,会调用handleSetOutputFormat()方法进行输出格式MIME类型的设置。然后调用PVAuthorEngine引擎的SelectComposer()方法进行组合器的选择。

PVAuthorEngine引擎首先向自身发送PVAE_CMD_SELECT_COMPOSER消息到事件队列中,一旦收到该消息,即调用DoSelectComposer()方法,根据消息携带的MIME类型获得相应的UUID,然后调用PVAuthorEngineNodeFactoryUtility::CreateComposer()方法创建组合器。接下来系统根据UUID判定是否创建MP4文件,如果是,则调用PVMp4FFComposerNodeFactory::CreateMp4FFComposer()方法创建MP4的组合器。

当开始媒体记录时,MP4组合器会被调用DoStart()方法,在该方法中,组合器会创建MP4文件,设置记录模式、缓冲等,然后设置时间戳、版本号、标题、作者、版权、备注等信息,后调用PVA_FF_IMpeg4File::prepareToEncode()方法开始编码工作。

需要说明的是,AuthorDriver为记录引擎和上层应用的接口,PlayerDriver为播放引擎与上层应用的接口。

 更多相关文章

·Android OpenCORE多媒体引擎
·Android PVPlayer引擎的实现
·Android OpenIPMP服务器搭建
·Android CPM插件机制
·Android 封装式/嵌入式DRM对比