這篇文章我們將聚焦Control API的功能與用法,為實現OMX Core、Component打下堅實的基礎。
1、OMX_Core.h
OMX Core在OpenMAX IL架構中的位置位於IL Client與實際的OMX元件之間,OMX Core提供了兩組API給IL Client使用,一組API用於管理OMX元件,另一組API用於操作/使用建立的OMX元件。
1.1
OMX_API OMX_ERRORTYPE OMX_APIENTRY OMX_Init(void);
OMX_Init
:OMX_Init用來初始化OMX Core,在第一次使用OMX元件前它需要先被呼叫,並且只被呼叫一次;初始化可能包含以下幾個步驟:- 分配並初始化使用OMX元件所需的記憶體和資源;
- 掃描系統中的所有可用OXM元件,並將它們載入到OMX Core中;
OMX_API OMX_ERRORTYPE OMX_APIENTRY OMX_Deinit(void);
OMX_Deinit
:與OMX_Init功能相反,它用作於解除安裝OMX_Init載入的資源;
OMX_API OMX_ERRORTYPE OMX_APIENTRY OMX_ComponentNameEnum(
OMX_OUT OMX_STRING cComponentName,
OMX_IN OMX_U32 nNameLength,
OMX_IN OMX_U32 nIndex);
OMX_ComponentNameEnum
:用於列舉OMX Core中可用的所有元件,該API包含三個引數,第一個引數cComponentName用於返回找到的元件名稱(輸出引數),第二個引數是字串的長度(輸入引數),第三個引數是遍歷OMX Core元件列表的索引,透過遞增索引並反覆呼叫這個函式,就可以列舉出OMX Core中所有的元件名稱,該API有兩個作用:- 當需要檢視 OMX Core 中有哪些可用的元件時,可以使用這個函式來獲取所有元件的名稱;
- 當需要透過名稱來查詢特定的元件時,可以使用這個函式來對所有元件進行遍歷,直到找到與給定名稱匹配的元件;
OMX_API OMX_ERRORTYPE OMX_APIENTRY OMX_GetHandle(
OMX_OUT OMX_HANDLETYPE* pHandle,
OMX_IN OMX_STRING cComponentName,
OMX_IN OMX_PTR pAppData,
OMX_IN OMX_CALLBACKTYPE* pCallBacks);
OMX_GetHandle
:用於建立一個OMX元件,返回的控制代碼就是我們前面學過的OMX_COMPONENTTYPE
,該函式需要傳遞四個引數:OMX_HANDLETYPE* pHandle
:這是一個二級指標void**,用於接收建立的OMX_COMPONENTTYPE指標;OMX_STRING cComponentName
:元件名稱,根據該名稱建立對應的元件;OMX_PTR pAppData
:呼叫者(Application/IL Client)的指標;OMX_CALLBACKTYPE* pCallBacks
:給OMX_COMPONENTTYPE註冊的回撥函式,用於回傳訊息;
OMX_API OMX_ERRORTYPE OMX_APIENTRY OMX_FreeHandle(
OMX_IN OMX_HANDLETYPE hComponent);
OMX_FreeHandle
:銷燬建立的OMX元件,傳入引數為OMX_HANDLETYPE hComponent
;
OMX_API OMX_ERRORTYPE OMX_APIENTRY OMX_SetupTunnel(
OMX_IN OMX_HANDLETYPE hOutput,
OMX_IN OMX_U32 nPortOutput,
OMX_IN OMX_HANDLETYPE hInput,
OMX_IN OMX_U32 nPortInput);
OMX_API OMX_ERRORTYPE OMX_GetContentPipe(
OMX_OUT OMX_HANDLETYPE *hPipe,
OMX_IN OMX_STRING szURI);
這兩個API Android中沒有用到,暫不瞭解。
OMX_API OMX_ERRORTYPE OMX_GetComponentsOfRole (
OMX_IN OMX_STRING role,
OMX_INOUT OMX_U32 *pNumComps,
OMX_INOUT OMX_U8 **compNames);
OMX_GetComponentsOfRole
:用於獲取在給定role(角色)下可以使用的所有OMX元件的列表,包含三個引數:OMX_STRING role
:Role是用來描述OMX元件功能的字串,每個OMX元件都擁有一個或多個角色,需要用role去指定OMX元件執行什麼任務,role的名字規律"video_decoder.avc"、"audio_encoder.aac",第一個欄位表示音訊/影片,下劃線後表示編碼/解碼,字尾表示具體的編解碼型別;OMX_U32 *pNumComps
:輸出引數,返回role對應的元件的數量;OMX_U8 **compNames
:輸出引數,返回role對應的所有元件的名稱
OMX_API OMX_ERRORTYPE OMX_GetRolesOfComponent (
OMX_IN OMX_STRING compName,
OMX_INOUT OMX_U32 *pNumRoles,
OMX_OUT OMX_U8 **roles);
OMX_GetRolesOfComponent
:獲取一個元件名對應的所有的Role,功能和OMX_GetComponentsOfRole類似;
根據OMX_Init和OMX_ComponentNameEnum等API中的描述,我們大致可以猜到,OMX Core中需要維護一個列表(map),列表中的內容是一組一組的Role和Component Name。
1.2
在OpenMAX IL框架設計中,IL Client不能直接訪問OMX元件的函式,它需要呼叫OMX Core提供的宏來間接操作OMX元件。要注意的是,OMX Core沒有為OMX元件的所有函式都提供宏,換言之有些OMX元件函式不是給IL Client使用的。
首先來看定義的宏:
#define OMX_SendCommand( \
hComponent, \
Cmd, \
nParam, \
pCmdData) \
((OMX_COMPONENTTYPE*)(hComponent))->SendCommand( \
hComponent, \
Cmd, \
nParam, \
pCmdData)
OMX_SendCommand用於傳送控制命令到元件,可用命令參考上文的列舉,該方法是非阻塞的,命令執行完成後需要傳送callback通知IL Client。包含有四個引數:
hComponent
:元件控制代碼;Cmd
:要傳送的命令型別;nParam
:int型別的命令引數;pCmdData
:無法使用int表示的命令引數;
#define OMX_GetParameter( \
hComponent, \
nParamIndex, \
pComponentParameterStructure) \
((OMX_COMPONENTTYPE*)(hComponent))->GetParameter( \
hComponent, \
nParamIndex, \
pComponentParameterStructure)
OMX_GetParameter用於從元件獲取引數設定,該方法為阻塞呼叫:
nParamIndex
:引數索引,用來指定獲取什麼引數;pComponentParameterStructure
:指標,用於裝載獲取到的引數;
#define OMX_SetParameter( \
hComponent, \
nParamIndex, \
pComponentParameterStructure) \
((OMX_COMPONENTTYPE*)(hComponent))->SetParameter( \
hComponent, \
nParamIndex, \
pComponentParameterStructure)
OMX_SetParameter用於給元件設定引數,該方法為阻塞呼叫,引數功能與OMX_GetParameter類似。
#define OMX_GetConfig( \
hComponent, \
nConfigIndex, \
pComponentConfigStructure) \
((OMX_COMPONENTTYPE*)(hComponent))->GetConfig( \
hComponent, \
nConfigIndex, \
pComponentConfigStructure)
#define OMX_SetConfig( \
hComponent, \
nConfigIndex, \
pComponentConfigStructure) \
((OMX_COMPONENTTYPE*)(hComponent))->SetConfig( \
hComponent, \
nConfigIndex, \
pComponentConfigStructure)
OMX_GetConfig和OMX_SetConfig分別用於從元件獲取配置、給元件設定配置,元件載入完成後可以
隨時呼叫這兩個方法,都是阻塞呼叫。不同於OMX_SetParameter設定的是元件的靜態引數值,SetConfig設定的是執行時可更改的配置資訊,例如影片的播放速度、音訊的音量、影片的亮度等。
#define OMX_GetExtensionIndex( \
hComponent, \
cParameterName, \
pIndexType) \
((OMX_COMPONENTTYPE*)(hComponent))->GetExtensionIndex( \
hComponent, \
cParameterName, \
pIndexType)
OMX_GetExtensionIndex用於將OMX IL或廠商定義的擴充套件字串轉換為相應的結構體索引,該方法是阻塞的。許多音訊和影片處理硬體具有特定的特性和特性,這些在OpenMAX IL標準中並未明確定義,為了使這些功能可以被利用,硬體廠商會提供特定的擴充套件;當應用程式需要訪問這些特定的擴充套件功能時,就需要使用OMX_GetExtensionIndex來獲取相關擴充套件的索引,然後使用這個索引去訪問或者操作這些特定的擴充套件功能。
#define OMX_GetState( \
hComponent, \
pState) \
((OMX_COMPONENTTYPE*)(hComponent))->GetState( \
hComponent, \
pState)
OMX_GetState用於獲取元件的當前狀態。
#define OMX_UseBuffer( \
hComponent, \
ppBufferHdr, \
nPortIndex, \
pAppPrivate, \
nSizeBytes, \
pBuffer) \
((OMX_COMPONENTTYPE*)(hComponent))->UseBuffer( \
hComponent, \
ppBufferHdr, \
nPortIndex, \
pAppPrivate, \
nSizeBytes, \
pBuffer)
OMX_UseBuffer用於讓元件使用由IL Client已經分配的buffer,或者使用tunneled元件已經提供的buffer。OMX_UseBuffer的實現應該分配出buffer header,並用引數填充它,最後透過ppBufferHdr返回。該方法是阻塞呼叫的,可以在LoadedToIdle狀態下使用,也可在OMX_StateExecuting、OMX_StateIdle且埠被禁用的情況下使用。
關注公眾號《青山渺渺》 獲取更多音影片開發內容