97干视频,99国产精品懂色,亚洲精品99久久久久中文字幕,伊人五月丁香综合AⅤ,国产精品成人免费999

  您的位置:華清遠(yuǎn)見教育科技集團(tuán) >> 新聞動態(tài) >> Android資料 >> OpenMAX IL 層接口的實現(xiàn)  
 
OpenMAX IL 層接口的實現(xiàn)
分享到:

《Android開發(fā)OpenMAX接口規(guī)范》一文中,我們了解到OpenMAX IL集成層的重要性。OpenMAX IL(Integration Layer)作為在嵌入式和移動設(shè)備中使用的音頻、視頻、圖像等編解碼器的底層接口,使得應(yīng)用和多媒體框架可以以統(tǒng)一的方式訪問多媒體編解碼器和支持組件,這就使得OpenMAX擁有跨平臺的能力。在OpenMAX IL的接口規(guī)范中,有些接口是廠商必須提供的,必須提供的方法如下:

1)OMX_API OMX_ERRORTYPE OMX_APIENTRY OMX_Init(void);
    2)OMX_API OMX_ERRORTYPE OMX_APIENTRY OMX_Deinit(void);
    3)OMX_API OMX_ERRORTYPE OMX_APIENTRY OMX_GetHandle(…);
    4)OMX_API OMX_ERRORTYPE OMX_APIENTRY OMX_FreeHandle(…);
    5)OMX_API OMX_ERRORTYPE OMX_APIENTRY OMX_ComponentNameEnum(...);
    6)OMX_API OMX_ERRORTYPE OMX_GetRolesOfComponent (…);
    7)OMX_API OMX_ERRORTYPE OMX_GetComponentsOfRole (…);
    8)OMX_API OMX_ERRORTYPE OMX_APIENTRY OMX_SetupTunnel(…);
    9)OMX_API OMX_ERRORTYPE OMX_GetContentPipe(…);

除以上方法必須實現(xiàn)外,為了使OpenCORE能夠獲悉OpenMAX Core的配置信息,OMXConfigParser()被強(qiáng)烈推薦實現(xiàn)。OMXConfigParser()的定義位于pv_omx_config_parser.h文件中。

在OpenCORE中,關(guān)于OpenMAX Core的實現(xiàn)位于pv_omxcore.cpp文件中?紤]在實際開發(fā)中,可能存在由多個廠商開發(fā)的OpenMAX Core實現(xiàn)的可能,為了避免造成靜態(tài)編譯時的鏈接問題,廠商在實現(xiàn)OpenMAX Core時,應(yīng)考慮增加一個簡單的封裝層。以封裝OpenMAX Core的標(biāo)準(zhǔn)接口。如在OpenCORE中,OMX_Init()接口的實現(xiàn)為:

OSCL_EXPORT_REF OMX_ERRORTYPE OMX_MasterInit()
    {
        return OMX_Init(); // OMX_Init()的具體實現(xiàn)位于同文件中
    }

在OpenCORE中,為上層提供的封裝接口為OMXInterface。由于采用的是動態(tài)加載的方法,考慮到可能存在多家廠商的OpenMAX Core情況,OpenMAX Core必須以動態(tài)庫的方式出現(xiàn)。在OpenCORE中,提供了兩種編譯模式。

一種編譯模式是封裝器和OpenMAX Core共享庫分別編譯。在OpenMAX Core動態(tài)庫中并不包含封裝器。該編譯模式的實現(xiàn)位于OpenCORE\codecs_v2\omx\ omx_core_ plugins\template\src\pv_omx_interface.cpp中。在PVOMXInterface類的構(gòu)造函數(shù)中,利用dlopen()函數(shù)以RTLD_NOW模式打開OpenMAX Core共享庫。為OpenMAX IL接口利用dlsym()函數(shù)查找對應(yīng)的符號進(jìn)行賦值。具體實現(xiàn)為:

代碼:封裝器和共享庫分別編譯

#ifndef OMX_CORE_LIBRARY
    #define OMX_CORE_LIBRARY "libOmxCore.so"
    #endif
    class PVOMXInterface : public OMXInterface
    {
      public:
      ……
      private:
      PVOMXInterface()
      {
        ipHandle=dlopen(OMX_CORE_LIBRARY, RTLD_NOW);//打開共享庫
        if (NULL==ipHandle)
        {
          pOMX_Init=NULL;
          pOMX_Deinit=NULL;
          pOMX_ComponentNameEnum=NULL;
          pOMX_GetHandle=NULL;
          pOMX_FreeHandle=NULL;
          pOMX_GetComponentsOfRole=NULL;
          pOMX_GetRolesOfComponent=NULL;
          pOMX_SetupTunnel=NULL;
          pOMX_GetContentPipe=NULL;
          pOMXConfigParser=NULL;
          const char* pErr=dlerror();
          if (NULL==pErr)
          {
          ……
          }
          else
          {
          ……
          }
        }
        else
        {
          //加載OMX core符號
          pOMX_Init=(tpOMX_Init)dlsym(ipHandle, "OMX_Init");
          pOMX_Deinit=(tpOMX_Deinit)dlsym(ipHandle, "OMX_Deinit");
          pOMX_ComponentNameEnum=(tpOMX_ComponentNameEnum)dlsym(ipHandle,
          "OMX_ComponentNameEnum");
          pOMX_GetHandle=(tpOMX_GetHandle)dlsym(ipHandle, "OMX_GetHandle");
          pOMX_FreeHandle=(tpOMX_FreeHandle)dlsym(ipHandle, "OMX_FreeHandle");
          pOMX_GetComponentsOfRole=(tpOMX_GetComponentsOfRole)dlsym(ipHandle,
          "OMX_GetComponentsOfRole");
          pOMX_GetRolesOfComponent=(tpOMX_GetRolesOfComponent)dlsym(ipHandle,
          "OMX_GetRolesOfComponent");
          pOMX_SetupTunnel=(tpOMX_SetupTunnel)dlsym(ipHandle, "OMX_SetupTunnel");
          pOMX_GetContentPipe=(tpOMX_GetContentPipe)dlsym(ipHandle,"OMX_GetContentPipe");
          pOMXConfigParser=(tpOMXConfigParser)dlsym(ipHandle, "OMXConfigParser");
        }
      };
    }

另一種編譯模式是封裝器和OpenMAX Core共享庫同時編譯。在OpenMAX Core動態(tài)庫中包含封裝器。該編譯模式的實現(xiàn)位于OpenCORE\codecs_v2\omx\ omx_ sharedlibrary\interface\src\ pv_omx_interface.cpp中。在該編譯模式下,只能同時編譯一個OpenMAX Core動態(tài)庫。具體實現(xiàn)為:

代碼:封裝器和共享庫同時編譯

class PVOMXInterface : public OMXInterface
    {
      public:
      ……
      private:
      PVOMXInterface()
      {
        //直接賦值
        pOMX_Init=OMX_Init;
        pOMX_Deinit=OMX_Deinit;
        pOMX_ComponentNameEnum=OMX_ComponentNameEnum;
        pOMX_GetHandle=OMX_GetHandle;
        pOMX_FreeHandle=OMX_FreeHandle;
        pOMX_GetComponentsOfRole=OMX_GetComponentsOfRole;
        pOMX_GetRolesOfComponent=OMX_GetRolesOfComponent;
        pOMX_SetupTunnel=OMX_SetupTunnel;
        pOMX_GetContentPipe=OMX_GetContentPipe;
        pOMXConfigParser=OMXConfigParser;
      };
    };

需要注意的是,不管是何種編譯模式,實現(xiàn)上均采用了單子模式(Singleton Pattern)的設(shè)計方法。在運行期間,PVOMXInterface僅有唯一對象出現(xiàn)。

為了使集成的編解碼器能夠在系統(tǒng)中運行,必須對編解碼器進(jìn)行注冊,在OpenCORE中,已經(jīng)提供了AVC、M4V(Apple公司開發(fā))、H.263、WMA、AAC、AMR、MP3、WMA、RV、RA等格式的解碼器,提供了AVC、M4V、H.263、AMR、AAC等格式的編碼器。在OpenMAX IL層中,編解碼器均是在Open Core的OMX_Init()函數(shù)中進(jìn)行注冊的,該函數(shù)的實現(xiàn)位于external\opencore\codecs_v2\omx\omx_common\src\pv_omxcore.cpp文件中,而編解碼器的注冊函數(shù)則位于external\opencore\codecs_v2\omx\omx_common\src\ pv_omxregistry.cpp文件中。編解碼器注冊的信息位于ComponentRegistrationType的對象中,ComponentRegistrationType的定義如下:

代碼:ComponentRegistrationType

class ComponentRegistrationType
    {
    public:
      OMX_STRING ComponentName; //組件名
      OMX_STRING RoleString[MAX_ROLES_SUPPORTED];
      OMX_U32 NumberOfRolesSupported; //角色數(shù)量
      OMX_ERRORTYPE(*FunctionPtrCreateComponent)(OMX_OUT OMX_HANDLETYPE* pHandle,OMX_IN OMX_PTR pAppData,OMX_PTR pProxy,OMX_STRING aOmxLibName,OMX_PTR &aOmxLib, OMX_PTR aOsclUuid,OMX_U32 &aRefCount);//創(chuàng)建組件
      OMX_ERRORTYPE(*FunctionPtrDestroyComponent)(OMX_IN OMX_HANDLETYPE pHandle,OMX_PTR &aOmxLib, OMX_PTR aOsclUuid, OMX_U32 &aRefCount);//銷毀組件
      void GetRolesOfComponent(OMX_STRING* aRole_string)
      {
        for (OMX_U32 ii=0; ii< NumberOfRolesSupported; ii++)
        {
          aRole_string[ii]=RoleString[ii];
        }
      }
    //用于動態(tài)加載
    OMX_STRING    SharedLibraryName;    //共享庫名
    OMX_PTR    SharedLibraryPtr;    //共享庫指針
    OMX_PTR    SharedLibraryOsclUuid;     //共享庫UUID
    OMX_U32    SharedLibraryRefCounter;    //共享庫引用計數(shù)
    };

為了進(jìn)行注冊,首先需要創(chuàng)建一個ComponentRegistrationType對象,對其成員進(jìn)行賦值,然后將其添加到OMXGlobalDatad的ipRegTemplateList[MAX_SUPPORTED_COMPONENTS]成員中。需要說明的是,在組件庫中的每個組件均有唯一的一個UUID來標(biāo)識,以MP3解碼器為例的注冊過程如下:

代碼:MP3Register

OMX_ERRORTYPE Mp3Register(OMXGlobalData *data)
    {
    OMX_S32 ii;
    ComponentRegistrationType *pCRT=(ComponentRegistrationType *) oscl_malloc(sizeof (ComponentRegistrationType));
    if (pCRT)
      {
      pCRT->ComponentName=(OMX_STRING)"OMX.PV.mp3dec"; //組件名
      pCRT->RoleString[0]=(OMX_STRING)"audio_decoder.mp3"; //角色名
      pCRT->NumberOfRolesSupported=1; //角色數(shù)量
      pCRT->SharedLibraryOsclUuid=NULL;
      #if USE_DYNAMIC_LOAD_OMX_COMPONENTS
      //構(gòu)造組件
      pCRT->FunctionPtrCreateComponent=&OmxComponentFactoryDynamicCreate;
      //析構(gòu)組件
      pCRT->FunctionPtrDestroyComponent=&OmxComponentFactoryDynamicDestructor;
      //共享庫名
      pCRT->SharedLibraryName=(OMX_STRING)"libomx_mp3dec_sharedlibrary";
      pCRT->SharedLibraryPtr=NULL;
      //UUID
      OsclUuid *temp=(OsclUuid *) oscl_malloc(sizeof(OsclUuid));
      if (temp==NULL)
      {
      //釋放已分配內(nèi)存
      oscl_free(pCRT);
      return OMX_ErrorInsufficientResources;
      }
      OSCL_PLACEMENT_NEW(temp, PV_OMX_MP3DEC_UUID);
      pCRT->SharedLibraryOsclUuid=(OMX_PTR) temp;
      pCRT->SharedLibraryRefCounter=0;
      #endif
      #if REGISTER_OMX_MP3_COMPONENT
      #if (DYNAMIC_LOAD_OMX_MP3_COMPONENT==0)
      pCRT->FunctionPtrCreateComponent=&Mp3OmxComponentFactory;
      pCRT->FunctionPtrDestroyComponent=&Mp3OmxComponentDestructor;
      pCRT->SharedLibraryName=NULL;
      pCRT->SharedLibraryPtr=NULL;
      if (pCRT->SharedLibraryOsclUuid)oscl_free(pCRT->SharedLibraryOsclUuid);
      pCRT->SharedLibraryOsclUuid=NULL;
      pCRT->SharedLibraryRefCounter=0;
      #endif
      #endif
      }
      else
      {
      return OMX_ErrorInsufficientResources;
      }
      for (ii=0; ii< MAX_SUPPORTED_COMPONENTS; ii++) //注冊組件
      {
        if (NULL==data->ipRegTemplateList[ii])
        {
          data->ipRegTemplateList[ii]=pCRT;
          break;
        }
      }
      if (MAX_SUPPORTED_COMPONENTS==ii)
      {
      return OMX_ErrorInsufficientResources;
      }
      return OMX_ErrorNone;
    }

每一個編解碼器在OpenMAX中都對應(yīng)唯一的一個 UUID標(biāo)識符。這些UUID標(biāo)識符定義位于pv_omxcore.h文件中。

 更多相關(guān)文章

·Android開發(fā)OpenMAX接口規(guī)范
·Android 圖像解碼的實現(xiàn)
·Android Camera 參數(shù)的設(shè)置
·Android Camera的HAL接口
·Android中Camera數(shù)據(jù)的處理