向OpenCORE裏繼承一個新的codec時,須要用到OpenMAX接口規範對該codec進行封裝,即要定義一個用於封裝的類(wrapper),實現OpenMAX規定的集中核心方法(omx core methods)。若該codec是一個音頻解碼器,則該類繼承OmxComponentAudio類;如果視頻解碼器,則繼承OmxComponentVideo類。而OmxComponentAudio和OmxComponentVideo類都是繼承了OmxComponentBase類;OmxComponentBase類又繼承自OsclActiveObject類。
爲了深刻點理解每OMX Component每一個接口(core methods)具體要實現些什麼功能,咱們逐一深刻這些相關的類的定義中。框架
【1】OsclActiveObject類ide
該類的定義在.../opencore/oscl/oscl/osclproc/src/oscl_scheduler_ao.h文件中。看給類的註釋:函數
/**spa
* User base class for execution objects.線程
* OsclActiveObject defines an execution object without any timer.代理
* This AO can be used across threads, i.e. the requestcode
* can be activated in one thread and completed in another.component
*/視頻
即該類是用於執行(或運行)對象的用戶基礎類,該運行對象沒有計時器。 這個正在運行的對象(AO)能夠在多個線程間被使用,如在一個線程中的請求能夠在另外一個線程中完成。
OsclActiveObject類又繼承自兩個類:HeapBase和PVActiveBase類,其中類HeapBase是用於基礎的堆操做,如分配、釋放內存等。類PVActiveBase主要是跟線程相關的(PV Scheduler internal AO base class)。
OsclActiveObject類主要是定義了對象運行的相關操做,如優先級、對象狀態等。
【2】OmxComponentBase類
其中一些接口涉及到proxy(代理??),不知道具體什麼差異!!!
/** Component entry points declarations without proxy interface*/
……
/** Component entry points declarations with proxy interface*/
……
接着是最重要的部分,
/*NON STATIC COUNTERPARTS OF STATIC MEMBER API'S */
//Pure virtual functions, definition to be written in derived class
/*
純虛函數,具體實如今派生的類中。
*/
virtual OMX_ERRORTYPE GetParameter(
OMX_IN OMX_HANDLETYPE hComponent,
OMX_IN OMX_INDEXTYPE nParamIndex,
OMX_INOUT OMX_PTR ComponentParameterStructure) = 0;
virtual OMX_ERRORTYPE SetParameter(
OMX_IN OMX_HANDLETYPE hComponent,
OMX_IN OMX_INDEXTYPE nParamIndex,
OMX_IN OMX_PTR ComponentParameterStructure) = 0;
virtual OSCL_IMPORT_REF OMX_ERRORTYPE GetConfig(
OMX_IN OMX_HANDLETYPE hComponent,
OMX_IN OMX_INDEXTYPE nIndex,
OMX_INOUT OMX_PTR pComponentConfigStructure);
//Making Setconfig as virtual function to be implemented in respective component class
// 在各個派生的component中各自實現該函數
virtual OSCL_IMPORT_REF OMX_ERRORTYPE SetConfig(
OMX_IN OMX_HANDLETYPE hComponent,
OMX_IN OMX_INDEXTYPE nIndex,
OMX_IN OMX_PTR pComponentConfigStructure);
……
/*OTHER PROCESSING FUNCTIONS */
//Pure virtual function called from base, must have a definition in derived components
//virtual void Decode() = 0;
/*
純虛函數,必須在派生的類中實現。
--> OmxComponentAudio --> omx_audio_xxx
--> OmxComponentVideo --> omx_video_xxx
該函數不是在OmxComponentAudio/OmxComponentVideo中實現,
而是在最終的派生類的實現,不一樣的編解碼器其實現過程是不同的。
*/
virtual void ProcessData() = 0;
……
/*
須要在派生的類(最終的component)中實現!!
*/
virtual OMX_ERRORTYPE ComponentInit() = 0;
virtual OMX_ERRORTYPE ComponentDeInit() = 0;
……
這些接口是每個OMX component都必須實現的函數(core methods),其中最重要的5種方法:
(1) ComponentInit()
(2) ComponentDeinit()
(3) GetParameter()
(4) SetParameter()
(5) ProcessData()
【3】OmxComponentAudio類
每一個音頻解碼器組件都必須繼承的類,其中GetParameter()和SetParameter()方法在該類中實現,其他方法在最終派生的component類中實現。
class OmxComponentAudio : public OmxComponentBase
{
public:
OSCL_IMPORT_REF OmxComponentAudio();
OSCL_IMPORT_REF virtual ~OmxComponentAudio();
OSCL_IMPORT_REF OMX_ERRORTYPE GetParameter(
OMX_IN OMX_HANDLETYPE hComponent,
OMX_IN OMX_INDEXTYPE nParamIndex,
OMX_INOUT OMX_PTR ComponentParameterStructure);
OSCL_IMPORT_REF OMX_ERRORTYPE SetParameter(
OMX_IN OMX_HANDLETYPE hComponent,
OMX_IN OMX_INDEXTYPE nParamIndex,
OMX_IN OMX_PTR ComponentParameterStructure);
virtual void UpdateAACPlusFlag(OMX_BOOL aAacPlusFlag)
{
OSCL_UNUSED_ARG(aAacPlusFlag);
}
OSCL_IMPORT_REF virtual void CalculateBufferParameters(OMX_U32 PortIndex);
};
注意:
由OmxComponentBase類繼承來的其餘虛函數,如ComponentInit(), ComponentDeinit(), ProcessData()等在這尚未具體實現。
【進一步分析GetParameter()和SetParameter()函數!!!!】
【4】OmxComponentVideo類
/*************************
VIDEO BASE CLASS ROUTINES
*************************/
class OmxComponentVideo : public OmxComponentBase
{
public:
OSCL_IMPORT_REF OmxComponentVideo();
OSCL_IMPORT_REF virtual ~OmxComponentVideo();
OSCL_IMPORT_REF OMX_ERRORTYPE GetParameter(
OMX_IN OMX_HANDLETYPE hComponent,
OMX_IN OMX_INDEXTYPE nParamIndex,
OMX_INOUT OMX_PTR ComponentParameterStructure);
OSCL_IMPORT_REF OMX_ERRORTYPE SetParameter(
OMX_IN OMX_HANDLETYPE hComponent,
OMX_IN OMX_INDEXTYPE nParamIndex,
OMX_IN OMX_PTR ComponentParameterStructure);
OSCL_IMPORT_REF virtual void CalculateBufferParameters(OMX_U32 PortIndex);
};
在OmxComponentVideo類中也是把從OmxComponentBase類中繼承來的虛函數GetParameter()和SetParameter()函數作了實現。
【5】OpenmaxMp3AO類
該類是對MP3解碼器按照openmax接口規範進行封裝的類,以便做爲一個音頻解碼的component集成進opencore框架中。
/*
按照openmax接口規範,對mp3 codec進行封裝!!
*/
class OpenmaxMp3AO : public OmxComponentAudio
{
public:
OpenmaxMp3AO();
~OpenmaxMp3AO();
OMX_ERRORTYPE ConstructComponent(OMX_PTR pAppData, OMX_PTR pProxy);
OMX_ERRORTYPE DestroyComponent();
OMX_ERRORTYPE ComponentInit(); // 繼承自OmxComponentAudio
OMX_ERRORTYPE ComponentDeInit(); // 繼承自OmxComponentAudio
void ProcessData(); // 繼承自OmxComponentAudio
void SyncWithInputTimestamp(); // 繼承自OmxComponentAudio
void ProcessInBufferFlag(); // 繼承自OmxComponentBase
void ResetComponent(); // 繼承自OmxComponentBase
OMX_ERRORTYPE GetConfig( // 覆蓋掉OmxComponentAudio中的實現
OMX_IN OMX_HANDLETYPE hComponent,
OMX_IN OMX_INDEXTYPE nIndex,
OMX_INOUT OMX_PTR pComponentConfigStructure);
private:
void CheckForSilenceInsertion();
void DoSilenceInsertion();
Mp3Decoder* ipMp3Dec; // 看具體實現!!!
Mp3TimeStampCalc iCurrentFrameTS;
};
【6】OpenmaxAvcAO類
該類是對H264解碼器按照openmax接口規範進行封裝的類,以便做爲一個視頻解碼的component集成進opencore框架中。
class OpenmaxAvcAO : public OmxComponentVideo
{
public:
OpenmaxAvcAO();
~OpenmaxAvcAO();
OMX_ERRORTYPE ConstructComponent(OMX_PTR pAppData, OMX_PTR pProxy);
OMX_ERRORTYPE DestroyComponent();
OMX_ERRORTYPE ComponentInit();
OMX_ERRORTYPE ComponentDeInit();
void ComponentBufferMgmtWithoutMarker();
OMX_BOOL ParseFullAVCFramesIntoNALs(OMX_BUFFERHEADERTYPE* aInputBuffer);
void ProcessData();
void DecodeWithoutMarker();
void DecodeWithMarker();
void ResetComponent();
void ReleaseReferenceBuffers();
OMX_ERRORTYPE GetConfig( // 覆蓋繼承類中的實現
OMX_IN OMX_HANDLETYPE hComponent,
OMX_IN OMX_INDEXTYPE nIndex,
OMX_INOUT OMX_PTR pComponentConfigStructure);
OMX_BOOL DetectStartCodeLength(OMX_U8* aBitstream,
OMX_U8** aNalUnit,
OMX_U32 aBufSize,
OMX_U32* aSCSize);
// ipOutputBuffer is fed to the decoder which may keep it as a reference
// The decoder "spits" out another output buffer for rendering
OMX_BUFFERHEADERTYPE *ipOutputBufferForRendering;
private:
AvcDecoder_OMX* ipAvcDec;
OMX_BOOL iDecodeReturn;
OMX_BOOL iFlushOutputStatus;
// variables for "frame" mode i.e. iOMXComponentNeedsFullAVCFrames is turned on
OMX_U32 iNALSizeArray[MAX_NAL_PER_FRAME]; // 100 should be more than enough NALs per frame
OMX_U32 iNALStartCodeSizeArray[MAX_NAL_PER_FRAME]; // 100 should be more than enough NALs per frame
OMX_U32 iCurrNAL;
OMX_U32 iNumNALs;
OMX_U32 iNALOffset;
OMX_U32 iSizeOfNALSize;
};