android 4.0.3中stagefright和openmax简述

 

在  android 4.0.3  SF和Openmax关系

   awesomplayer.cpp 中 awesomeplay有一个成员 OMXClient mClient;
   这个mClient是通过MediaPlayerService的getOmx()方法创建(new OMX),代码如下
sp<IOMX> MediaPlayerService::getOMX() {
    Mutex::Autolock autoLock(mLock);

    if (mOMX.get() == NULL) {
        mOMX = new OMX;
    }

    return mOMX;
}  
可以跟综OMX.cpp这个文件,查看创建过程 
OMX::OMX()
    : mMaster(new OMXMaster),
      mNodeCounter(0) {
}
mNodeCounter:omxnode 计数器,在OmxCodec.cpp中返回nodeid
mMaster 这个对象是omx核心 可以理解为服务器端,之后在Omxcodec.cpp中create时传入的mOmx是mclient,它的所有调用都会通过IOMX.cpp转到Omx.cpp中。
下面我们来重点分析一下 OMXMaster
OMXMaster::OMXMaster()
    : mVendorLibHandle(NULL) {
    addVendorPlugin();
    addPlugin(new SoftOMXPlugin);
}
通过addPlugin添加openmax外挂的插件,可以拿 addPlugin(new SoftOMXPlugin)为例,在SoftOMXPlugin插件中包含了支持的所有解码器组件,在我们的系统中支持的解码组件如下:

static const struct {
    const char *mName;
    const char *mLibNameSuffix;
    const char *mRole;

} kComponents[] = {
    { "OMX.google.aac.decoder", "aacdec", "audio_decoder.aac" },
    { "OMX.google.amrnb.decoder", "amrdec", "audio_decoder.amrnb" },
    { "OMX.google.amrwb.decoder", "amrdec", "audio_decoder.amrwb" },
    { "OMX.google.h264.decoder", "h264dec", "video_decoder.avc" },
    { "OMX.google.g711.alaw.decoder", "g711dec", "audio_decoder.g711alaw" },
    { "OMX.google.g711.mlaw.decoder", "g711dec", "audio_decoder.g711mlaw" },
    { "OMX.google.h263.decoder", "mpeg4dec", "video_decoder.h263" },
    { "OMX.google.mpeg4.decoder", "mpeg4dec", "video_decoder.mpeg4" },
    { "OMX.google.mp3.decoder", "mp3dec", "audio_decoder.mp3" },
    { "OMX.google.vorbis.decoder", "vorbisdec", "audio_decoder.vorbis" },
    { "OMX.google.vpx.decoder", "vpxdec", "video_decoder.vpx" },
};
addPlugin(softomxplugin)时,会把调用SoftOmXPlugin的enumerateComponents,依次把上面这些组件添加到OMXMaster 的mPluginByComponentName中。
在omxcodec.cpp中创建组件时:
 status_t err = omx->allocateNode(componentName, observer, &node);
会依次根据componentName,通过iomx.cpp(ibinder)->omx.cpp->OMXMaster.cpp中的makeComponentInstance
 OMXMaster的makeComponentInstance会根据componentName名字查找到具体插件,比如componentName是OMX.google.vorbis.decoder,则会找到SoftOMXPlugin插件(vorbis这个组件包含在SoftOMXPlugin插件中,从上数据可以看出来),然后要据componentname调用插件SoftOMXPlugin->makeComponentInstance的方法,生成真正的组件(对应的解码器)。代码如下
OMX_ERRORTYPE SoftOMXPlugin::makeComponentInstance(
        const char *name,
        const OMX_CALLBACKTYPE *callbacks,
        OMX_PTR appData,
        OMX_COMPONENTTYPE **component) {
    LOGV("makeComponentInstance '%s'", name);

    for (size_t i = 0; i < kNumComponents; ++i) {
        if (strcmp(name, kComponents[i].mName)) {
            continue;
        }
        AString libName = "libstagefright_soft_";
        libName.append(kComponents[i].mLibNameSuffix);
        libName.append(".so");
        void *libHandle = dlopen(libName.c_str(), RTLD_NOW);
        if (libHandle == NULL) {
            LOGE("unable to dlopen %s", libName.c_str());
            return OMX_ErrorComponentNotFound;
        }

        typedef SoftOMXComponent *(*CreateSoftOMXComponentFunc)(
                const char *, const OMX_CALLBACKTYPE *,
                OMX_PTR, OMX_COMPONENTTYPE **);

        CreateSoftOMXComponentFunc createSoftOMXComponent =
            (CreateSoftOMXComponentFunc)dlsym(
                    libHandle,
                    "_Z22createSoftOMXComponentPKcPK16OMX_CALLBACKTYPE"
                    "PvPP17OMX_COMPONENTTYPE");

        if (createSoftOMXComponent == NULL) {
            dlclose(libHandle);
            libHandle = NULL;

            return OMX_ErrorComponentNotFound;
        }

        sp<SoftOMXComponent> codec =
            (*createSoftOMXComponent)(name, callbacks, appData, component);

        if (codec == NULL) {
            dlclose(libHandle);
            libHandle = NULL;

            return OMX_ErrorInsufficientResources;
        }

        OMX_ERRORTYPE err = codec->initCheck();
        if (err != OMX_ErrorNone) {
            dlclose(libHandle);
            libHandle = NULL;

            return err;
        }

        codec->incStrong(this);
        codec->setLibHandle(libHandle);

        return OMX_ErrorNone;
    }

    return OMX_ErrorInvalidComponentName;
}
从上面代码可以看出来,SoftOMXPlugin->makeComponentInstance会根据传过来组件的名字,寻找对应的
libstagefright_soft_vorbisdec.so库,然后加载库中的CreateSoftOMXComponentFunc函数,然后调用它,来创建真正的解码器。由此可以看出,libstagefright_soft_vorbisdec.so这个库就是对应一个解码器组件。根据lcomponentname的不同加载不同的库,创建不同的解码器。好了,到现在为止大家对4.0.3中使用openmax有个大概了解。
下面强调几点
  1:libstagefright_soft_vorbisdec.so 对应的解码器组件,要有标准接口。set/getparameter,set/getconfig等openmax标准接口
  2:本文中说的组件和插件稍有不同,读者自已分析一下。组件可以认为涉及低层了 属于openmax的DL而之上的插件属于IL,可以这样理解,不知道对不对。
       3:以ogg的setparameter为例,明确调用流程 
    omx.cpp(ibinder)->omx.cpp->OMXMaster.cpp->OMXNodeInstance.cpp->omx_core.h(setparameter)->具体组件的setparameter( SoftVorbis::internalSetParameter)
下面简述一下softvorbis解码器创建流程。
  awesomplayer.cpp initAudioDecoder()->omxcodec:create()它会在这里调用
        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, flags,
                    createEncoder, mime, componentName,
                    source, nativeWindow);
  之后返回codec,至此codec创建完成。
  awesomplayer.cpp得到的codec 赋值给mAudioSource.
        mAudioSource = OMXCodec::Create(//此处将mAudioTrack传给codec,mAudioTrack相当于文件数据,mClient相当于OMX bp接口。
                mClient.interface(), mAudioTrack->getFormat(),
                false, // createEncoder
                mAudioTrack);
    之后awesomplayer.cpp接到收的start,read/pause等,都会转化为mAudioSource的start,read,等。
 mAudioSource的read相当于读取解码器的数据,然后送给mAudioPlayer。
 mAudioPlayer将pcm->HAL(Audioflinger)->alsa->kernel.
采用openmax形式的 和 SF原来不使用openmax方式类似 不采用openmax时,mAudioSource返回的直接就是解码器对应的类。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值