在AwesomePlayer中会调用

mVideoSource= OMXCodec::Create(

mClient.interface(),mVideoTrack->getFormat(),

false, // createEncoder

mVideoTrack,

NULL,flags, USE_SURFACE_ALLOC ? mNativeWindow : NULL);

来获得videoSource,在这个函数中,会首先查找当前的在kKeyMIMEType并存入mime字串中,然后调用findMatchingCodecs,在这个函数中会判断是Decoder还是Encoder,以Decoder为例,会在kDecoderInfo这个结构体中查找与mime匹配的字串,如果成功获得componentName,则加入到matchingCodecs中。另外,这里要注意的是,如果flags中定义了kPreferSoftwareCodecs,则会重新排序,将软件编解码模块加到前面。

matchingCodecs->clear();

for (int index = 0;; ++index) {
const char *componentName;

if (createEncoder) {
componentName = GetCodec(
kEncoderInfo,
sizeof(kEncoderInfo) / sizeof(kEncoderInfo[0]),
mime, index);
} else {
componentName = GetCodec(
kDecoderInfo,
sizeof(kDecoderInfo) / sizeof(kDecoderInfo[0]),
mime, index);
}

if (!componentName) {
break;
}

if (matchComponentName && strcmp(componentName, matchComponentName)) {
continue;
}

if (((flags & kSoftwareCodecsOnly) && IsSoftwareCodec(componentName)) ||
((flags & kHardwareCodecsOnly) && !IsSoftwareCodec(componentName)) ||
(!(flags & (kSoftwareCodecsOnly | kHardwareCodecsOnly)))) {

matchingCodecs->push(String8(componentName));
}
}

if (flags & kPreferSoftwareCodecs) {
matchingCodecs->sort(CompareSoftwareCodecsFirst);
}

然后,对matchingCodecs中的每个编解码器,按照先后顺序,先看是否是软件编解码器,如果是的,则直接返回软件编解码器即可,如果是硬件的,则需先分配结点,调用allocateNode函数,这个是IOMX类的一个纯虚函数。这里涉及到binder机制,不是很清楚,大致描述下。首先会调用Client端的(IOMX.cpp)BnOMX的allocateNode函数,这里会调用remote的tranact(请求发送并要求返回调用结果)函数来传递ALLOCATE_NODE消息,这就会调用Server端的(OMX.cpp)BpOMX的allocateNode函数,继续会调用到mMaster(OMXMaster.cpp)的makeComponentInstance函数,这边关键是追传进去的name参数。接着会调用到plugin的makeComponentInstance函数,这边会先由指定的name生成index,再由index来生成OMXPluginBase类的对象plugin。

for (size_t i = 0; i < matchingCodecs.size(); ++i) {
componentName = matchingCodecs[i].string();

sp<MediaSource> softwareCodec = createEncoder?
InstantiateSoftwareEncoder(componentName, source, meta):
InstantiateSoftwareCodec(componentName, source);

if (softwareCodec != NULL) {
LOGV("Successfully allocated software codec '%s'", componentName);

return softwareCodec;
}

LOGV("Attempting to allocate OMX node '%s'", componentName);

uint32_t quirks = getComponentQuirks(componentName, createEncoder);

if (!createEncoder
&& (quirks & kOutputBuffersAreUnreadable)
&& (flags & kClientNeedsFramebuffer)) {
if (strncmp(componentName, "OMX.SEC.", 8)) {
// For OMX.SEC.* decoders we can enable a special mode that
// gives the client access to the framebuffer contents.

LOGW("Component '%s' does not give the client access to "
"the framebuffer contents. Skipping.",
componentName);

continue;
}
}

status_t err = omx->allocateNode(componentName, observer, &node);
if (err == OK) {
LOGV("Successfully allocated OMX node '%s'", componentName);

sp<OMXCodec> codec = new OMXCodec(
omx, node, quirks,
createEncoder, mime, componentName,
source, nativeWindow);

observer->setCodec(codec);

err = codec->configureCodec(meta, flags);

if (err == OK) {
return codec;
}

LOGV("Failed to configure codec '%s'", componentName);
}
}


new OMXCodec是根据获取的结点来创建编解码器的,对于后面的observer->setCodec(codec)及codec->configureCodec(meta, flags)只是对编加码器的一些配置工作,没有细看。

转载请注明出处:http://blog.csdn.net/qq69696698

更多相关文章

  1. Android(安卓)widget 之RemoteView
  2. Android(安卓)AudioManager控制系统声音的流程
  3. Android(安卓)jni 编程(参数的传递,成员,方法的)相互访问
  4. android JB2连拍降速原理介绍
  5. Android多媒体开发【11】-- android中OpenMax的实现【2】Awesome
  6. android绘制过程
  7. Android 开机动画源码分析
  8. Android System Server大纲之LightsService

随机推荐

  1. Android之系统自带的文字外观设置及实际
  2. android跨进程通信(IPC):使用AIDL
  3. Android如何代码混淆
  4. Android中Timer使用示例
  5. Android(安卓)test project 编译步骤
  6. Android(安卓)办公自动化(Office Automati
  7. 【Android】EditText实现搜索功能,把键盘
  8. android的第一天学习
  9. Android工具之Hierarchy Viewer--分析应
  10. 离线下载安装android sdk