stagefright 架构分析(八) 怎么获取ComponentHandle,plugin与omx_core桥接

stagefright 架构分析(八) 如何获取ComponentHandle,plugin与omx_core桥接

目前基于高通的code分析:

1. 引入libOmxCore.so

根据stagefright 架构分析(七) 动态加载libstagefrighthw.so中的描述

Plugin会加载libOmxCore.so,并调用相应的functions

OMX_Init

OMX_Deinit

OMX_ComponentNameEnum

OMX_GetHandle

OMX_FreeHandle

OMX_GetRolesOfComponent

2. libOmxCore.so 编译内容

LOCAL_SRC_FILES         := src/common/omx_core_cmp.cpp
LOCAL_SRC_FILES         += src/common/qc_omx_core.c
LOCAL_SRC_FILES         += src/$(MM_CORE_TARGET)/qc_registry_table_android.c

3. Plugin调用functions

调用的functions在qc_omx_core.c实现

QComOMXPlugin中通过dlsym得到的函数指针,是在qc_omx_core.c中实现的。

例如        mInit = (InitFunc)dlsym(mLibHandle, "OMX_Init");

               (*mInit)();

最终调用的是

OMX_API OMX_ERRORTYPE OMX_APIENTRY
OMX_Init()
{
  DEBUG_PRINT("OMXCORE API - OMX_Init \n");
  /* Nothing to do here ; shared objects shall be loaded at the get handle method */
  return OMX_ErrorNone;
}

4. OMX_COMPONENTTYPE interface

component interface在omx_core_cmp.cpp中实现:

具体看这个函数,就容易理解了

void * qc_omx_create_component_wrapper(OMX_PTR obj_ptr)
{
    qc_omx_component *pThis        = (qc_omx_component *)obj_ptr;
    OMX_COMPONENTTYPE* component   = &(pThis->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;
    component->AllocateBuffer      = &qc_omx_component_allocate_buffer;
    component->FreeBuffer          = &qc_omx_component_free_buffer;
    component->GetParameter        = &qc_omx_component_get_parameter;
    component->SetParameter        = &qc_omx_component_set_parameter;
    component->SendCommand         = &qc_omx_component_send_command;
    component->FillThisBuffer      = &qc_omx_component_fill_this_buffer;
    component->EmptyThisBuffer     = &qc_omx_component_empty_this_buffer;
    component->GetState            = &qc_omx_component_get_state;
    component->GetComponentVersion = &qc_omx_component_get_version;
    component->GetConfig           = &qc_omx_component_get_config;
    component->SetConfig           = &qc_omx_component_set_config;
    component->GetExtensionIndex   = &qc_omx_component_get_extension_index;
    component->ComponentTunnelRequest = &qc_omx_component_tunnel_request;
    component->UseBuffer           = &qc_omx_component_use_buffer;
    component->SetCallbacks        = &qc_omx_component_set_callbacks;
    component->UseEGLImage         = &qc_omx_component_use_EGL_image;
    component->ComponentRoleEnum   = &qc_omx_component_role_enum;
    component->ComponentDeInit     = &qc_omx_component_deinit;
    return (void *)component;
}

5. 如何获取ComponentHandle

OMX_ERRORTYPE QComOMXPlugin::makeComponentInstance(
        const char *name,
        const OMX_CALLBACKTYPE *callbacks,
        OMX_PTR appData,
        OMX_COMPONENTTYPE **component) {

//调用GetHandle,注册callbacks,并用name得到component句柄
    return (*mGetHandle)(
            reinterpret_cast<OMX_HANDLETYPE *>(component),
            const_cast<char *>(name),
            appData, const_cast<OMX_CALLBACKTYPE *>(callbacks));
}


 OMX_API OMX_ERRORTYPE OMX_APIENTRY
OMX_GetHandle(OMX_OUT OMX_HANDLETYPE*     handle,
              OMX_IN OMX_STRING    componentName,
              OMX_IN OMX_PTR             appData,
              OMX_IN OMX_CALLBACKTYPE* callBacks)

{

//根据componentName获得对应的component的index

    cmp_index = get_cmp_index(componentName);

      // dynamically load the so
      core[cmp_index].fn_ptr =
        omx_core_load_cmp_library(core[cmp_index].so_lib_name,
                                  &core[cmp_index].so_lib_handle);

      //创建instance指针地址

        void* pThis = (*(core[cmp_index].fn_ptr))();
        if(pThis)
        {
          void *hComp = NULL;

          //这就是前面注册component
          hComp = qc_omx_create_component_wrapper((OMX_PTR)pThis);

          //初始化component
          if((eRet = qc_omx_component_init(hComp, core[cmp_index].name)) !=
                           OMX_ErrorNone)

          qc_omx_component_set_callbacks(hComp,callBacks,appData);

          //得到component handle的index
          hnd_index = get_comp_handle_index(componentName);
          if(hnd_index >= 0)
          {

            //最终将创建好的component handle返回
            core[cmp_index].inst[hnd_index]= *handle = (OMX_HANDLETYPE) hComp;
          }

}

6. 如何根据ComponentName找到对应的handle呢?

static int get_cmp_index(char *cmp_name)
{
  for(i=0; i< (int)SIZE_OF_CORE; i++)
  {
    if(!strcmp(cmp_name, core[i].name))
    {
        rc = i;
        break;
    }
  }
  return rc;
}

可以看到,是根据全局数组core中找到的

core的定义在$(MM_CORE_TARGET)/qc_registry_table_android.c

不同的TARGET有不同的定义

omx_core_cb_type core[] =
{
  {
    "OMX.qcom.video.decoder.avc",
    NULL, // Create instance function
    // Unique instance handle
    {
      NULL,
      NULL,
      NULL,
      NULL
    },
    NULL,   // Shared object library handle
    "libOmxVdec.so",
    {
      "video_decoder.avc"
    }
  },
  {
    "OMX.qcom.video.decoder.avc.secure",
    NULL, // Create instance function
    // Unique instance handle
    {
      NULL,
      NULL,
      NULL,
      NULL
    },
    NULL,   // Shared object library handle
    "libOmxVdec.so",
    {
      "video_decoder.avc"
    }
  },
  {
    "OMX.qcom.video.decoder.divx4",
    NULL,   // Create instance function
    // Unique instance handle
    {
      NULL,
      NULL,
      NULL,
      NULL
    },
    NULL,   // Shared object library handle
    "libOmxVdec.so",
    {
      "video_decoder.divx"
    }
  },
  {
    "OMX.qcom.video.decoder.divx",
    NULL,   // Create instance function
    // Unique instance handle
    {
      NULL,
      NULL,
      NULL,
      NULL
    },
    NULL,   // Shared object library handle
    "libOmxVdec.so",
    {
      "video_decoder.divx"
    }
  },
  {
    "OMX.qcom.video.decoder.divx311",
    NULL,   // Create instance function
    // Unique instance handle
    {
      NULL,
      NULL,
      NULL,
      NULL
    },
    NULL,   // Shared object library handle
    "libOmxVdec.so",
    {
      "video_decoder.divx"
    }
  },
  {
    "OMX.qcom.video.decoder.mpeg4",
    NULL, // Create instance function
    // Unique instance handle
    {
      NULL,
      NULL,
      NULL,
      NULL
    },
    NULL,   // Shared object library handle
    "libOmxVdec.so",
    {
      "video_decoder.mpeg4"
    }
  },
  {
    "OMX.qcom.video.decoder.mpeg2",
    NULL, // Create instance function
    // Unique instance handle
    {
      NULL,
      NULL,
      NULL,
      NULL
    },
    NULL,   // Shared object library handle
    "libOmxVdec.so",
    {
      "video_decoder.mpeg2"
    }
  },
  {
    "OMX.qcom.video.decoder.vc1",
    NULL, // Create instance function
    // Unique instance handle
    {
      NULL,
      NULL,
      NULL,
      NULL
    },
    NULL,   // Shared object library handle
    "libOmxVdec.so",
    {
      "video_decoder.vc1"
    }
  },
  {
    "OMX.qcom.video.decoder.wmv",
    NULL, // Create instance function
    // Unique instance handle
    {
      NULL,
      NULL,
      NULL,
      NULL
    },
    NULL,   // Shared object library handle
    "libOmxVdec.so",
    {
      "video_decoder.vc1"
    }
  },
  {
    "OMX.qcom.video.decoder.h263",
    NULL, // Create instance function
    // Unique instance handle
    {
      NULL,
      NULL,
      NULL,
      NULL
    },
    NULL,   // Shared object library handle
    "libOmxVdec.so",
    {
      "video_decoder.h263"
    }
  },
   {
    "OMX.qcom.video.encoder.mpeg4",
    NULL, // Create instance function
    // Unique instance handle
    {
      NULL,
      NULL,
      NULL,
      NULL
    },
    NULL,   // Shared object library handle
    "libOmxVenc.so",
    {
      "video_encoder.mpeg4"
    }
  },
   {
    "OMX.qcom.video.encoder.h263",
    NULL, // Create instance function
    // Unique instance handle
    {
      NULL,
      NULL,
      NULL,
      NULL
    },
    NULL,   // Shared object library handle
    "libOmxVenc.so",
    {
      "video_encoder.h263"
    }
  },
   {
    "OMX.qcom.video.encoder.avc",
    NULL, // Create instance function
    // Unique instance handle
    {
      NULL,
      NULL,
      NULL,
      NULL
    },
    NULL,   // Shared object library handle
    "libOmxVenc.so",
    {
      "video_encoder.avc"
    }
  },
  {
    "OMX.qcom.audio.decoder.Qcelp13",
    NULL, // Create instance function
    // Unique instance handle
    {
      NULL,
      NULL,
      NULL,
      NULL
    },
    NULL,   // Shared object library handle
    "libOmxQcelp13Dec.so",
    {
      "audio_decoder.Qcelp13"
    }
  },
  {
    "OMX.qcom.audio.decoder.evrc",
    NULL, // Create instance function
    // Unique instance handle
    {
      NULL,
      NULL,
      NULL,
      NULL
    },
    NULL,   // Shared object library handle
    "libOmxEvrcDec.so",
    {
      "audio_decoder.evrc"
    }
  },
  {
    "OMX.qcom.audio.decoder.wma",
    NULL, // Create instance function
    // Unique instance handle
    {
     NULL,
     NULL,
     NULL,
     NULL
    },
    NULL,   // Shared object library handle
    "libOmxWmaDec.so",
    {
     "audio_decoder.wma"
    }
  },
  {
    "OMX.qcom.audio.decoder.wma10Pro",
    NULL,   // Create instance function
    // Unique instance handle
    {
     NULL,
     NULL,
     NULL,
     NULL
    },
    NULL,   // Shared object library handle
    "libOmxWmaDec.so",
    {
     "audio_decoder.wma"
    }
  },
  {
    "OMX.qcom.audio.decoder.aac",
    NULL,   // Create instance function
    // Unique instance handle
    {
      NULL,
      NULL,
      NULL,
      NULL
    },
    NULL,   // Shared object library handle
    "libOmxAacDec.so",
    {
      "audio_decoder.aac"
    }
  },
  {
    "OMX.qcom.audio.encoder.aac",
    NULL, // Create instance function
    // Unique instance handle
    {
      NULL,
      NULL,
      NULL,
      NULL
    },
    NULL,  // Shared object library handle
    "libOmxAacEnc.so",
    {
      "audio_encoder.aac"
    }
  },
  {
    "OMX.qcom.audio.encoder.qcelp13",
    NULL,   // Create instance function
    // Unique instance handle
    {
      NULL,
      NULL,
      NULL,
      NULL
    },
    NULL,   // Shared object library handle
    "libOmxQcelp13Enc.so",
    {
      "audio_encoder.qcelp13"
    }
  },
  {
    "OMX.qcom.audio.encoder.evrc",
    NULL,   // Create instance function
    // Unique instance handle
    {
      NULL,
      NULL,
      NULL,
      NULL
    },
    NULL,   // Shared object library handle
    "libOmxEvrcEnc.so",
    {
      "audio_encoder.evrc"
    }
  },
  {
    "OMX.qcom.audio.encoder.amrnb",
    NULL,   // Create instance function
    // Unique instance handle
    {
      NULL,
      NULL,
      NULL,
      NULL
    },
    NULL,   // Shared object library handle
    "libOmxAmrEnc.so",
    {
      "audio_encoder.amrnb"
    }
  },
 {
    "OMX.qcom.audio.decoder.aac",
    NULL,   // Create instance function
    // Unique instance handle
    {
      NULL,
      NULL,
      NULL,
      NULL
    },
    NULL,   // Shared object library handle
    "libOmxAacDec.so",
    {
      "audio_decoder.aac"
    }
  },
 {
    "OMX.qcom.audio.decoder.multiaac",
    NULL,   // Create instance function
    // Unique instance handle
    {
      NULL,
      NULL,
      NULL,
      NULL
    },
    NULL,   // Shared object library handle
    "libOmxAacDec.so",
    {
      "audio_decoder.aac"
    }
  },
  {
    "AIV.play",
    NULL, // Create instance function
    // Unique instance handle
    {
      NULL,
      NULL,
      NULL,
      NULL
    },
    NULL,  // Shared object library handle
    "libAivPlay.so",
    {
      "AIV.play.101"
    }
  },
  {
    "OMX.qcom.file.muxer",
    NULL, // Create instance function
    // Unique instance handle
    {
      NULL,
      NULL,
      NULL,
      NULL
    },
    NULL,   // Shared object library handle
    "libOmxMux.so",
    {
      "container_muxer.mp2"
    }
  }
};


const unsigned int SIZE_OF_CORE = sizeof(core) / sizeof(omx_core_cb_type);