OpenMAX确立了一套标准的接口,上层App直接调用这些接口,底层硬件厂商直接实现这些接口,
从而实现了上层软件开发与底层芯片开发地彻底分离,加速了跨平台的多媒体组件的开发、整合和编程。
Android上的MediaCodec是通过ACodec来加载openmax层,了解OMX加载过程,有助于我们更好的分析问题和解决问题
加载过程还需从ACodec::UninitializedState::onAllocateComponent接口说起。
1、onAllocateComponent
bool ACodec::UninitializedState::onAllocateComponent(const sp<AMessage> &msg) {
……
for (size_t matchIndex = 0; matchIndex < matchingCodecs.size();
++matchIndex) {
componentName = matchingCodecs[matchIndex];
OMXClient client;
bool trebleFlag;
if (client.connect(owners[matchIndex].c_str(), &trebleFlag) != OK) {
mCodec->signalError(OMX_ErrorUndefined, NO_INIT);
return false;
}
omx = client.interface();
pid_t tid = gettid();
int prevPriority = androidGetThreadPriority(tid);
androidSetThreadPriority(tid, ANDROID_PRIORITY_FOREGROUND);
err = omx->allocateNode(componentName.c_str(), observer, &omxNode);
androidSetThreadPriority(tid, prevPriority);
if (err == OK) {
mCodec->setTrebleFlag(trebleFlag);
ALOGE("codec %s selected", componentName.c_str());
break;
} else {
ALOGE("Allocating component '%s' failed, try next one.", componentName.c_str());
}
omxNode = NULL;
}
可以简单理解为两步
1、获取OMX句柄
2、分配component
1.1 获取OMX句柄
我们可以将此过程理解为 C/S模型,客户端/服务器模型
运行在mediaserver或者app进程内的 MediaCodec是 client
运行在media.codec进程内的component是 server
MediaCodec通过 OMXClient,经过binder进程间通讯, 向MediaCodecService获取 OMX句柄
如下:
OMXClient client;
bool trebleFlag;
if (client.connect(owners[matchIndex].c_str(), &trebleFlag) != OK) {
mCodec->signalError(OMX_ErrorUndefined, NO_INIT);
return false;
}