android MediaCodec ACodec OMX tips

1、ACodec消息机制:

ACodec有一个BaseState和派生出来的其他State,如 UninitializedState,LoadedToIdleState, ExecutingState等。当有消息过来时,如果派生类有重写的方法,则会调到重写的方法,如果没有,则会调到BaseState的方法。

ACodec继承自AHierarchicalStateMachine类,该类用于将收到的消息传递给哪个state。

ACodec收到的消息分两种,一种是MediaCodec传过来的,对应onMessageReceived方法;另一种是OMXComponent传过来的,对应onOMXMessage方法。而onOMXMessage里面又分了4种情况来调用不同的方法。(EVENT、EMPTY_BUFFER_DONE、FILL_BUFFER_DONE和FRAME_RENDERED)

 

2、ACodec向MediaCodec的通知(例)

OMX的组件解码之后,ACodec::BaseState::onOMXFillBufferDone (…)会被回调,去取得解码后的数据。然后会在onOMXFillBufferDone中调用notify通知MediaCodec,发给MediaCodec的消息形如notify->setInt32("what",CodecBase::kWhatDrainThisBuffer); 然后notify->post();

MediaCodec收到ACodec的消息后做相应处理,调updateBuffers(kPortIndexOutput,msg) 进行更新,同时调用onOutputBufferAvailable()中通知NuPlayer::Decoder有可用的outputbuffer。

 

3、 ACodec的三种端口模式状态

其会根据当前处于哪个状态来决定buffer如何处理:

KEEP_BUFFERS:当ACodec处于BaseState或者收到OnInputBufferFilled消息但是buffer里面没有填充有效的数据时,ACodec握有的buffer不会送到OMX 组件;

RESUBMIT_BUFFERS:当ACodec处于ExecutingState或者处于OutputPortSettingChangedState但是当前是input口的buffer时,ACodec将握有的buffer送给OMX 组件;

FREE_BUFFERS:当ACodec处于OutputPortSettingChangedState并且当前是output口的buffer时,ACodec将握有的buffer释放掉。

 

4、OMX相关介绍

OMXNodeInstance负责创建并维护不同的实例,这些实例以node_id作为唯一标识。这样播放器中每个ACodec在OMX服务端都对应有了自己的OMXNodeInstance实例。

OMXMaster用来维护底层软硬件解码库,根据OMXNodeInstance中想要的解码器来创建解码实体组件。

OMXPluginBase负责加载组件库,创建组件实例,由OMXMaster管理。Android原生提供的组件都是由SoftOMXPlugin类来管理,这个类就是继承自OMXPluginBase。(Android源码提供了一些软件解码和编码的组件,它们被抽象为SoftOMXComponent)

OMXClient是客户端用来与OMX IL进行通信的。

内部结构CallbackDispatcher作用是用来接收回调函数的消息

OMXNodeInstance同 CallbackDispatcher一起完成不同实例的消息处理任务


5、OMX回调机制

android MediaCodec ACodec OMX tips

android MediaCodec ACodec OMX tips

然后组件保存回调函数指针

android MediaCodec ACodec OMX tips

当组件内部完成相关操作后,就会调用到其notifyXXX函数,对应各自的回调函数
android MediaCodec ACodec OMX tips

OMXNodeInstance的回调函数会调到OMX的相应函数(ower是OMX类型的指针)
        OMXNodeInstance::OnEvent调到instance->owner()->OnEvent
        OMXNodeInstance::OnEmptyBufferDone调到instance->owner()->OnEmptyBufferDone

        OMXNodeInstance::OnFillBufferDone调到instance->owner()->OnFillBufferDone


以OnEmptyBufferDone为例,在OMX的相应函数中有(另外两个类似)

android MediaCodec ACodec OMX tips

回调消息分发器处理消息CallbackDispatcher::post,即回调分发器post消息
 android MediaCodec ACodec OMX tips
CallbackDispatcher启动之后一直在循环:OMX::CallbackDispatcher::loop(),其中会调用到dispatch
 android MediaCodec ACodec OMX tips

然后CallbackDispatcher::dispatch处理消息,进入到OMXNodeInstance的onMessages,让OMXNodeInstance继续处理消息
 android MediaCodec ACodec OMX tips

CodecObserver的onMessages处理,即客户端(ACodec)处理OMX返回来的消息。CodecObserver里面dup出kWhatOMXMessageList消息,发往ACodec处理。

android MediaCodec ACodec OMX tips


6、 组件的加载

l OMXMaster的makeComponentInstance方法根据组件的名字,找到对应的OMXPluginBase对象(如SoftOMXPlugin)。然后调用OMXPluginBase的makeComponentInstance方法获得OMX_COMPONENTTYPE对象的指针,并将OMX_COMPONENTTYPE对象的指针保存在形参中返回。

android MediaCodec ACodec OMX tips


8、组件的管理

对组件的管理可以总结为:通过OMXMaster加载libstagefrighthw.so库文件,创建OMXPluginBase【即创建继承此类的组件对象,如SoftOMXPlugin】,通过这个类来管理组件。

OMXPluginBase负责加载组件库,创建组件实例。而OMXMaster则管理着OMXPluginBase,Android原生提供的组件都包含在SoftOMXPlugin中,这个类就是继承自OMXPluginBase。另外,Android源码提供了一些软件解码和编码的组件,它们被抽象为SoftOMXComponent。

对于厂商来说,如果要实现自己的组件管理模块,需要通过继承实现OMXPluginBase,并将之编译为libstagefrighthw.so。在OMXMaster中会加载这个库文件,然后调用其createOMXPlugin方法获得一个OMXPluginBase指针,然后将其加入OMXPluginBase列表以及mPluginByComponentName(加载时用到)中,后续都会通过OMXPluginBase来管理组件。

android MediaCodec ACodec OMX tips