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)
{