MediaCodec到OMX框架过程
在讲NuPlayer时,NuPlayer解码部分会创建MediaCodec,并且最终到达OMX框架,先看MediaCodec的init 函数
从init函数中可以看到,首先创建了ACodec ,并且初始化了ALooper 、AMessage ,由于ACodec继承自AHandler ,那么一套消息机制就有了。最后发送kWhatInit 消息,收到消息的逻辑位于ACodec.cpp中
主要是调用了ACodec的initiateAllocateComponent 函数
同样发送了一个kWhatAllocateComponent 消息,消息中心收到后,会调用onAllocateComponent 回调函数
通过该函数主要是先判断OMXClient和Server是否正常建立了连接,然后通过IOMX进行IPC通信,接着调用omx->allocateNode 分配Node节点
同理看看onConfigureComponent
上面的代码会调用ACodec的configureCodec 函数,由于太长不予展示,该函数用于构建一些编解码器,包括各种不同的音频编解码器和视频编解码器
MediaCodec硬解码
其调用的是在系统中注册过的解码器,硬件厂商会把自己的硬解码器注册进来,这就是硬解码(GPU负责),如果厂商注册一个软解码器,则是软解码(CPU负责)
MediaCodec并不是真正的编解码器,真正的编解码器在OMX 中,要保证是硬解码,在MediaCodec里有接口可以枚举所有解码器,每种编码可能都有多个解码器,区分哪个是软解码哪个是硬解码就行。如通过mime构建MediaCode:MediaCodec mediacodec=MediaCodec.createDecoderByType("video/avc")
从其函数的注释中我们可以看到其枚举了哪些编解码器
接下来看一下Android系统中解码器的命名方式,软解码器通常是以OMX.google开头,硬解码器通常是以OMX.[hardware_vendor] 开头,比如MTK的解码器以OMX.MTK开头,也有不遵守这个命名规范的,不以OMX.开头的情况也会被认为是软解码器
MediaCodec调用的是系统中注册的解码器,系统中可以存在很多解码器,但能够被应用的解码器是根据配置来的,即/system/etc/media_codecs.xml 。这个文件一般由硬件或者系统的生产厂家在编译整个系统的时候提供,一般保存在代码的device/[company]/[codename] 目录下。这个文件配置了系统中有哪些可用的Codec以及这些Codec对应的媒体文件类型。在这个文件里面,系统提供的软硬编解码器都需要被列出来。如果系统实际包含某个Codec但没配置在该文件中,那么应用程序也无法使用。
在这个配置文件里如果出现多个Codec对应同样类型的媒体格式,这些Codec都会被保留。当系统使用时会选择第一个匹配的Codec,除非指明了要软还是硬解码。但在framework层为上层提供服务的AwesomePlayer处理音频和视频的时候对选择软硬解码的参数没有设置。所以虽然底层支持选择,但对于上层使用MediaPlayer的java程序来说还是只能接受默认的Codec选取规则
android提供的命令行程序/system/bin/stagefright 在播放音频文件的时候,可以根据参数来选择软硬解码,但该工具只支持播放音频。一般来说如果系统有对应的媒体硬件解码器那么我们总是会用到。在极少数情况下硬件解码器存在但不配置,有可能是这个硬件解码器还有Bug暂时不适合发布,所以不使用
|