stagefright 架构分析(六) 创建一个 Soft Decoder

参考代码

在android中,已经有一些soft decoder,例如AAC AMR AVC等,这些都是软解的decoder,如果想自己加入一种decoder,可以参照这些代码的写法。
例如frameworks/av/media/libstagefright/codecs/
aacdec/     amrnb/      amrwbenc/   avc/        flac/       m4v_h263/   on2/        vorbis/
aacenc/     amrwb/      Android.mk  common/     g711/       mp3dec/     raw/

soft Decoder是如何载入的

android中decoder的管理是以plugin的模式,其控制是在OMXMaster内完成的。
//OMXMaster是在omx被创建时就创建了
OMX::OMX()
    : mMaster(new OMXMaster),
      mNodeCounter(0) {
}
//Plugin在OMXMaster构造的时候就载入了
OMXMaster::OMXMaster()
    : mVendorLibHandle(NULL) {
//创建硬解码Plugin
    addVendorPlugin();
//创建软解码的Plugin
    addPlugin(new SoftOMXPlugin);
}

void OMXMaster::addPlugin(OMXPluginBase *plugin) {
    Mutex::Autolock autoLock(mLock);
//将这个plugin放进mPlugins
    mPlugins.push_back(plugin);
    OMX_U32 index = 0;
    char name[128];
    OMX_ERRORTYPE err;
    while ((err = plugin->enumerateComponents(
                    name, sizeof(name), index++)) == OMX_ErrorNone) {
        String8 name8(name);
        if (mPluginByComponentName.indexOfKey(name8) >= 0) {
            ALOGE("A component of name '%s' already exists, ignoring this one.",
                 name8.string());
            continue;
        }
将Plugin的名字和plugin加入到mPluginByComponentName中
        mPluginByComponentName.add(name8, plugin);
    }
}

//具体载入的实现是在SoftOMXPlugin中:
static const struct {
//component name
    const char *mName;
//生成的plugin名字的最后名字,例如aac dec:libstagefright_soft_aacdec.so
    const char *mLibNameSuffix;
//职责
    const char *mRole;
} kComponents[] = {
    { "OMX.google.aac.decoder", "aacdec", "audio_decoder.aac" },
    { "OMX.google.aac.encoder", "aacenc", "audio_encoder.aac" },
    { "OMX.google.amrnb.decoder", "amrdec", "audio_decoder.amrnb" },
    { "OMX.google.amrnb.encoder", "amrnbenc", "audio_encoder.amrnb" },
    { "OMX.google.amrwb.decoder", "amrdec", "audio_decoder.amrwb" },
    { "OMX.google.amrwb.encoder", "amrwbenc", "audio_encoder.amrwb" },
    { "OMX.google.h264.decoder", "h264dec", "video_decoder.avc" },
    { "OMX.google.h264.encoder", "h264enc", "video_encoder.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.h263.encoder", "mpeg4enc", "video_encoder.h263" },
    { "OMX.google.mpeg4.decoder", "mpeg4dec", "video_decoder.mpeg4" },
    { "OMX.google.mpeg4.encoder", "mpeg4enc", "video_encoder.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" },
    { "OMX.google.raw.decoder", "rawdec", "audio_decoder.raw" },
    { "OMX.google.flac.encoder", "flacenc", "audio_encoder.flac" },
};

OMX_ERRORTYPE SoftOMXPlugin::makeComponentInstance(
        const char *name,
        const OMX_CALLBACKTYPE *callbacks,
        OMX_PTR appData,
        OMX_COMPONENTTYPE **component) {
    for (size_t i = 0; i < kNumComponents; ++i) {
        if (strcmp(name, kComponents[i].mName)) {
            continue;
        }
//libName名字必须是libstagefright_soft_"kComponents[i].mLibNameSuffix".so
        AString libName = "libstagefright_soft_";
        libName.append(kComponents[i].mLibNameSuffix);
        libName.append(".so");
//通过dlopen调用
        void *libHandle = dlopen(libName.c_str(), RTLD_NOW);

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

//调用该plugin的createSoftOMXComponent函数,每个Plugin必须实现这个方法
        CreateSoftOMXComponentFunc createSoftOMXComponent =
            (CreateSoftOMXComponentFunc)dlsym(
                    libHandle,
                    "_Z22createSoftOMXComponentPKcPK16OMX_CALLBACKTYPE"
                    "PvPP17OMX_COMPONENTTYPE");

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

            return OMX_ErrorInsufficientResources;
        }
    return OMX_ErrorInvalidComponentName;
}

如何加入一个soft decoder

首先,可以参考某个soft decoder plugin,这个plugin必须实现
android::SoftOMXComponent *createSoftOMXComponent(
        const char *name, const OMX_CALLBACKTYPE *callbacks,
        OMX_PTR appData, OMX_COMPONENTTYPE **component) 

然后,在SoftOMXPlugin中加入kComponents[],参照原有的定义自己的。
在Android.mk中的编译选项
LOCAL_MODULE :=  libstagefright_soft_"kComponents[i].mLibNameSuffix"
include $(BUILD_SHARED_LIBRARY)

最终编译出来libstagefright_soft_"kComponents[i].mLibNameSuffix".so这个库

你可能感兴趣的:(android,media)