Andriod4.03 stagefright 中 OpenMax 的实现 
----黄添喜 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
一. OpenMax  简介 
1.  Component    Architecture
 
2.  State Transitions   
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
二. OMX  的创建 
1.OMX  创建示意图 
 
 
2.实际创建过程
z:\mydroid-cleaning\frameworks\base\media\libmediaplayerservice\StagefrightRecorder.cpp 
在函数 status_t StagefrightRecorder::setupVideoEncoder 中 
OMXClient client; 
//通过 MediaPlayerService binder 获取 OMX binder 
CHECK_EQ(client.connect(),OK);  
------------------------------------------------------------------ 
\frameworks\base\media\libstagefright\OMXClient.cpp 
status_t OMXClient::connect()  
{ 
     sp sm = defaultServiceManager(); 
     sp binder = sm->getService(String16("media.player")); 
     sp service = interface_cast(binder); 
    CHECK(service.get() != NULL); 
    mOMX = service->getOMX(); 
    CHECK(mOMX.get() != NULL); 
    return OK; 
} 
------------------------------------------------------------------ 
 \frameworks\base\media\libmediaplayerservice\MediaPlayerService.cpp 
sp MediaPlayerService::getOMX()  
{ 
    if (mOMX.get() == NULL)  
{ 
        mOMX = new OMX; 
    } 
    return mOMX; 
} 
 
 
 
------------------------------------------------------------------ 
OMX::OMX() 
    : mMaster(new OMXMaster), 
      mNodeCounter(0) 
 {} 
 
 
------------------------------------------------------------------ 
OMXMaster::OMXMaster() 
: mVendorLibHandle(NULL) 
 { 
       addVendorPlugin(); 
       addPlugin(new SoftOMXPlugin); 
} 
 
 
 
------------------------------------------------------------------ 
a void OMXMaster::addPlugin(const char *libname)   
{ 
            1.  从 libstagefrighthw.so  中动态装载 createOMXPlugin  ,这里也就是找到  new 
TIOMXPlugin 的函数 
  
            2.        OMXPluginBase *Ti_plugin = (*createOMXPlugin)();//创建 TIPlugIn  对象     
            3.        再次调用 addPlugIn    2    addPlugin((*createOMXPlugin)()); 
} 
OMX_BuildComponentTable, 根据 tComponentName 初始化全局变量 CompTab 
typedef struct _ComponentTable 
 { 
    OMX_STRING name;//Componet 名称,无标准 
 
    OMX_U16 nRoles;//Componet 中 Roles 的数量,标准                                     
   //Role 名称指针数值 
    OMX_STRING pRoleArray[MAX_ROLES]; 
}ComponentTable; 
------------------------------------------------------------------ 
//对 VenderPlugIn 和 softPlugIn 都调用该函数 
void OMXMaster::addPlugin(OMXPluginBase *plugin)  
{ 
    mPlugins.push_back(plugin); 
    char name[128]; 
    while ((err = plugin->enumerateComponents(name, sizeof(name), index++)) == OMX_ErrorNone)  
    { 
        String8 name8(name); 
        mPluginByComponentName.add(name8, plugin); 
    } 
 } 
 
三.Component 的创建 
1.  创建流程                 
 
 
2.具体实现 
sp
 OMXCodec::Create( 
                const sp &omx, 
                const sp &meta, bool createEncoder, 
                const sp &source, 
                const char *matchComponentName, 
                uint32_t flags, 
                const sp &nativeWindow)   
{ 
        ……. 
        const char *mime; 
      //  获取之前设定了编码算法   
      // enc_meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC); 
        bool success = meta->findCString(kKeyMIMEType, &mime); 
        CHECK(success); 
  
        Vector matchingCodecs; 
  
  //1.查找有哪些 Component 支持 MEDIA_MIMETYPE_VIDEO_AVC 
/************************************************************ 
        查找结果如下,flag  可以指定选用软编码或者硬编码 
        { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.TI.DUCATI1.VIDEO.H264E" }, 
        { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.qcom.7x30.video.encoder.avc" }, 
        { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.qcom.video.encoder.avc" }, 
        { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.TI.Video.encoder" }, 
        { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.Nvidia.h264.encoder" }, 
        { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.SEC.AVC.Encoder" }, 
        { MEDIA_MIMETYPE_VIDEO_AVC, "AVCEncoder" },软编码 
          // OMX.google.前缀,  没有前缀的也是为 soft 
          // OMX.前缀的为硬编码 
/***************************************************************** 
        findMatchingCodecs(mime, createEncoder, matchComponentName, flags, 
&matchingCodecs); 
  
        if (matchingCodecs.isEmpty())   
{ 
                return NULL; 
        } 
//2.创建 OMXCodecObserver 
        sp observer = new OMXCodecObserver; 
        IOMX::node_id node = 0; 
  
        for (size_t i = 0; i < matchingCodecs.size(); ++i)   
{