標籤:enum lag 原始碼 auto find new 統一 dia memset
本文均屬自己閱讀原始碼的點滴總結。轉賬請註明出處謝謝。
歡迎和大家交流。
qq:1037701636 email:[email protected]
Android原始碼版本號碼Version:4.2.2; 硬體平台 全志A31
之所以單獨把這塊內容提煉出來,在於其具備的一定的層次性,結構上具備統一性,API函數的設計須要實現OMX架構專屬的介面。
1. 在上一博文Android4.2.2下Stagefright多媒體架構中的A31的OMX外掛程式和Codec組件 中我們提到。通過Binder架構,在MPS的線程上建立完一個實際的轉碼器節點後,擷取到了一個node:node_id。例如以下所看到的將會依據相關的節點資訊,建立一個MPS側的OMXCodec結構體,作為相似本地的一個轉碼器。
..... sp<OMXCodec> codec = new OMXCodec( omx, node, quirks, flags, createEncoder, mime, componentName, source, nativeWindow);//建立一個本地OMXCodec解碼器。node成為興許的操作的關鍵IOMX::node_id//omx為Master observer->setCodec(codec);//將解碼器交給observer err = codec->configureCodec(meta);//依據資料來源配置本地的這個解碼器........
在configureCodec對這個解碼器的配置中。我們能夠看到一些對之前分配的解碼器節點的控制操作。
我們以它當中的一個函數調用為例,進行控制流程的層層分析:
setVideoOutputFormat(mMIME, meta);//設定視頻輸出格式
mOMX->getParameter(mNode, OMX_IndexParamPortDefinition, &def, sizeof(def))
這裡看到mOMX是在建立AwesomePlayer時擷取的一個匿名的BpOMX對象。
終於的實如今MediaPlayerService中的中的OMX對象來實現getParameter。
2.OMX對象下的操作。
status_t OMX::getParameter( node_id node, OMX_INDEXTYPE index, void *params, size_t size) { return findInstance(node)->getParameter( index, params, size);}
findInstance(node)這裡就是依據這個node_id來擷取之前注冊的一個OMXNodeInstance對象執行個體:
OMXNodeInstance *OMX::findInstance(node_id node) { Mutex::Autolock autoLock(mLock); ssize_t index = mNodeIDToInstance.indexOfKey(node); return index < 0 ? NULL : mNodeIDToInstance.valueAt(index);}
終於就變成了例如以下的調用:
status_t OMXNodeInstance::setParameter( OMX_INDEXTYPE index, const void *params, size_t size) { Mutex::Autolock autoLock(mLock); OMX_ERRORTYPE err = OMX_SetParameter( mHandle, index, const_cast<void *>(params)); return StatusFromOMXError(err);}
3.OMX_XXX的實現
#define OMX_GetParameter( hComponent, nParamIndex, ComponentParameterStructure) ((OMX_COMPONENTTYPE*)hComponent)->GetParameter( hComponent, nParamIndex, ComponentParameterStructure) /* Macro End */
OMX_SetParameter等宏函數是OMX_CORE的核心所在。也是原來OpenOMx裡的OMX IL層的體現。來看mHandle的類型,作為一個OMXNodeInstance對象的成員變數。他維護著之前makeComponentInstance返回的一個對底層編解碼組件庫的控制代碼。這裡看上去就是一個OMX節點執行個體,一個控制代碼可操作最下層的解碼組件。能夠看到handle轉為OMX_COMPONENTTYPE類型。
裡看看其的結構體類型:
typedef struct OMX_COMPONENTTYPE{ OMX_U32 nSize; OMX_VERSIONTYPE nVersion; OMX_COMPONENTNAMETYPE eCompName; OMX_PTR pComponentPrivate; OMX_ERRORTYPE (*GetParameter)( OMX_IN OMX_HANDLETYPE hComponent, OMX_IN OMX_INDEXTYPE nIndex, OMX_IN OMX_PTR ComponentParameterStructure);...............
這個handle的擷取是在之前建立解碼器節點時完畢的,通過須要建立的解碼器的name,通過OMX外掛程式庫,再進入到libOmxCore.so(OMX IL固有結構)調用OMX_GetHandle來擷取相應組件name下的平台解碼庫libOmxVdec.so。或者libOmxVenc.so等。
這個handle通過下面完畢初始化:
void* aw_omx_create_component_wrapper(OMX_PTR obj_ptr){ aw_omx_component *pThis = (aw_omx_component *)obj_ptr;//omx_vdec對象 OMX_COMPONENTTYPE* component = &(pThis->m_cmp);//對m_cmp進行初始化 memset(&pThis->m_cmp,0,sizeof(OMX_COMPONENTTYPE)); component->nSize = sizeof(OMX_COMPONENTTYPE); component->nVersion.nVersion = OMX_SPEC_VERSION; component->pApplicationPrivate = 0; component->pComponentPrivate = obj_ptr;//儲存著omx_vdec這個對象 component->AllocateBuffer = &aw_omx_component_allocate_buffer; component->FreeBuffer = &aw_omx_component_free_buffer; component->GetParameter = &aw_omx_component_get_parameter; component->SetParameter = &aw_omx_component_set_parameter; component->SendCommand = &aw_omx_component_send_command; component->FillThisBuffer = &aw_omx_component_fill_this_buffer; component->EmptyThisBuffer = &aw_omx_component_empty_this_buffer; component->GetState = &aw_omx_component_get_state; component->GetComponentVersion = &aw_omx_component_get_version; component->GetConfig = &aw_omx_component_get_config; component->SetConfig = &aw_omx_component_set_config; component->GetExtensionIndex = &aw_omx_component_get_extension_index; component->ComponentTunnelRequest = &aw_omx_component_tunnel_request; component->UseBuffer = &aw_omx_component_use_buffer; component->SetCallbacks = &aw_omx_component_set_callbacks; component->UseEGLImage = &aw_omx_component_use_EGL_image; component->ComponentRoleEnum = &aw_omx_component_role_enum; component->ComponentDeInit = &aw_omx_component_deinit; return (void *)component;}
通過以上的賦值操作,我們關注這個component->pComponentPrivate = obj_ptr,他是將硬體平台的解碼器執行個體維護到handle結構體中。由於終於的操作肯定都要回到最底層的解碼器控制。
這也就是OMX IL的架構給予了開發人員的方便性和規劃化。通過這個我們就能夠總結出須要下面幾個檔案來銜接更底層的轉碼器:
xxx_omx_core.c和omx_core_cmp.c兩個源檔案來完畢。前者提供向上的介面用於建立轉碼器執行個體。後者提供比如上述的xxx_omx_component_api介面的實現,而實際事實上現是調用的是編解碼的相關API來處理:
OMX_ERRORTYPE aw_omx_component_get_parameter(OMX_IN OMX_HANDLETYPE hComp, OMX_IN OMX_INDEXTYPE paramIndex, OMX_INOUT OMX_PTR paramData){OMX_ERRORTYPE eRet = OMX_ErrorBadParameter;aw_omx_component *pThis = (hComp)? (aw_omx_component *)(((OMX_COMPONENTTYPE *)hComp)->pComponentPrivate):NULL;DEBUG_PRINT("OMXCORE: aw_omx_component_get_parameter %x, %x , %d\n",(unsigned)hComp,(unsigned)paramData,paramIndex);if(pThis){eRet = pThis->get_parameter(hComp,paramIndex,paramData);}return eRet;}
這裡的pThis技術當前最底層的解碼器組件的控制入口。即所謂的aw_omx_component的衍生類別對象。
這樣也就是說明了我們自己要構建的編解碼須要實aw_omx_component的相關介面函數,能夠看到這裡我們最底層的解碼器組件就是對這些函數的實現,加快了自己定義一個新的組件類型,下面是幾個介面的定義和實現:
OMX_ERRORTYPE omx_vdec::set_parameter(OMX_IN OMX_HANDLETYPE hComp, OMX_IN OMX_INDEXTYPE paramIndex, OMX_IN OMX_PTR paramData)
OMX_ERRORTYPE omx_vdec::get_parameter(OMX_IN OMX_HANDLETYPE hComp, OMX_IN OMX_INDEXTYPE paramIndex, OMX_INOUT OMX_PTR paramData)
到這裡我們基本走通了從OMXCodec到對最底層的轉碼器組件的控制,層次分明。介面規範帶給我們的是高速開發,我們須要做的核心是在自己的轉碼器組件中實現相關的業務,而這和自身的硬體平台具有緊密性。
4.總結建立一個屬於stagefright下OMX的編解碼組件須要做的事情
我們所要做的核心工作就在libOmxCore.so和libOmxVdec.so這兩個庫檔案的設計。
但都須要符合OMX的協議就可以。
分析了那麼多的控制流程,也已經有了所謂的OMXCodec,那麼興許主要內容將是資料流的處理。
Android4.2.2下Stagefright下OMX轉碼器組件的控制流程