达令假货:Android StageFright之OpenMAX的實現

来源:百度文库 编辑:中财网 时间:2024/05/09 09:09:42

Android StageFright之OpenMAX的實現

OMXCodec是一個MediaSource,完成資料的parse和decode。而OMXCodec則主要通過IOMX跨越OpenBinder機制操作OMX來實現。

重點介紹一下OMX。OMX主要完成三個任務,NodeInstance列表的管理,針對一個NodeInstance的操作以及事件的處理。

一、NodeInstance列表的管理。

這個主要包括NodeInstance的生成(allocateNode)和刪除(freeNode)。其實就是對mDispatchers和 mNodeIDToInstance進行添加和刪除。mNodeIDToInstance就是一個key為node_id,value為 NodeInstance的名值對列表。而mDispatchers就是一個key為node_id,value為 OMX::CallbackDispatcher的名值對列表。並且,一個NodeInstance都擁有一個 OMX::CallbackDispatcher。


二、NodeInstance節點的操作。

主要成員函數如下:

sendCommand

getParameter

setParameter

... ...

fillBuffer

emptyBuffer

getExtensionIndex

這些方法執行時,都是先通過findInstance在mNodeIDToInstance列表中找到對應的NodeInstance,然後調用NodeInstance對應的方法。


三、事件處理

先看一下OMXNodeInstance.cpp中的這樣一段代碼:

OMX_CALLBACKTYPE OMXNodeInstance::kCallbacks = {

    &OnEvent, &OnEmptyBufferDone, &OnFillBufferDone

};

它把三個OMXNodeInstance類的靜態方法註冊給了kCallbacks。而kCallbacks在哪裡使用呢?看一下OMX.cpp中的allocateNode方法中的代碼:

OMX_ERRORTYPE err = mMaster->makeComponentInstance(

            name, &OMXNodeInstance::kCallbacks,

            instance, &handle);

事件處理函數傳給了元件ComponentInstance。當組件有事件發生時,就會調用OMXNodeInstance中這幾個註冊過的事件處理函數,而這幾個函數又會去調用OMX中對應的函數,也就是下面這三個:

OnEvent、OnEmptyBufferDone、OnFillBufferDone。

這幾個方法都採用相同的路子:根據node_id找到CallbackDispatcher,並把事件資訊post過去。具體點兒,就是調用findDispatcher(node)->post(msg)。

這裡不得不提一下CallbackDispatcher的實現機制。它內部開啟了一個執行緒,使用了信號量機制。可以看一下OMX::CallbackDispatcher的屬性:Condition mQueueChanged;

可以看出findDispatcher(node)->post(msg)是一個非同步作業,只把msg給POST過去,不會等待事件處理完畢就返回了。那麼CallbackDispatcher是怎麼處理接收到的msg呢?看以下代碼:

OMX::CallbackDispatcher::threadEntry()

          dispatch(msg);

     mOwner->onMessage(msg);

mObserver->onMessage(msg);

這個mObserver是哪來的?OMXCodec::Create中初始化IOMX時傳入的。

sp observer = new OMXCodecObserver;

... ...

omx->allocateNode(componentName, observer, &node);

這樣算下來,事件最終還是跨越OpenBinder又傳到了OMXCodec裡面去,交給OMXCodecObserver了。

對節點的操作

NodeInstance的大部分方法的實現,如sendCommand等,都是通過OMX_Core.h中的巨集定義間接調用 OMX_Component.h中的OMX_COMPONENTTYPE這個struct中的相應函數指標來完成。在這裡提到的OMX_Core.h和 OMX_Component.h都是OpenMAX標準標頭檔