方法1:注册Plugin
device/qcom/common/media/media_codecs.xml
<MediaCodecs>
<Encoders>
<!-- Audio Hardware -->
<MediaCodec name="OMX.google.aac.encoder" type="audio/mp4a-latm" />
<MediaCodec name="OMX.qcom.audio.encoder.aac" type="audio/mp4a-latm" />
...
</Encoders> <Decoders>
<!-- Audio Hardware --> <MediaCodec name="OMX.qcom.audio.decoder.Qcelp13Hw" type="audio/qcelp" > <Quirk name="requires-global-flush" /> </MediaCodec> <MediaCodec name="OMX.qcom.audio.decoder.evrchw" type="audio/evrc" > <Quirk name="requires-global-flush" /> </MediaCodec>
如果是Decoder则在xml文件的Decoder部分加一行描述新加Codec的信息,注意Codec名称必须以OMX.开头:<MediaCodec name="OMX.my.aac" type="audio/mp4a-latm" />
如果Codec需要初始化,则可以在OMXCodec::configureCodec中加入codec相关的初始化代码:
status_t OMXCodec::configureCodec(const sp<MetaData> &meta) { ... } else if (meta->findData(kKeyAVCC, &type, &data, &size)) { // Parse the AVCDecoderConfigurationRecord unsigned profile, level; status_t err; if ((err = parseAVCCodecSpecificData( data, size, &profile, &level)) != OK) { ALOGE("Malformed AVC codec specific data."); return err; } QCOMXCodec::checkIfInterlaced((const uint8_t *)data, meta);
实现Plugin并编译成libstagefright_my.so:
OMXMaster.cpp
OMXMaster::OMXMaster() : mVendorLibHandle(NULL) { addVendorPlugin(); addPlugin(new SoftOMXPlugin); } void OMXMaster::addVendorPlugin() { addPlugin("libstagefrighthw.so"); } void OMXMaster::addPlugin(const char *libname) { mVendorLibHandle = dlopen(libname, RTLD_NOW); if (mVendorLibHandle == NULL) { return; } typedef OMXPluginBase *(*CreateOMXPluginFunc)(); CreateOMXPluginFunc createOMXPlugin = (CreateOMXPluginFunc)dlsym( mVendorLibHandle, "createOMXPlugin"); if (!createOMXPlugin) createOMXPlugin = (CreateOMXPluginFunc)dlsym( mVendorLibHandle, "_ZN7android15createOMXPluginEv"); if (createOMXPlugin) { addPlugin((*createOMXPlugin)()); } }
void OMXMaster::addPlugin(OMXPluginBase *plugin) { Mutex::Autolock autoLock(mLock); 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; } mPluginByComponentName.add(name8, plugin); } if (err != OMX_ErrorNoMore) { ALOGE("OMX plugin failed w/ error 0x%08x after registering %d " "components", err, mPluginByComponentName.size()); } }
OMX_ERRORTYPE OMXMaster::makeComponentInstance( const char *name, const OMX_CALLBACKTYPE *callbacks, OMX_PTR appData, OMX_COMPONENTTYPE **component) { Mutex::Autolock autoLock(mLock); *component = NULL; ssize_t index = mPluginByComponentName.indexOfKey(String8(name)); if (index < 0) { return OMX_ErrorInvalidComponentName; } OMXPluginBase *plugin = mPluginByComponentName.valueAt(index); OMX_ERRORTYPE err = plugin->makeComponentInstance(name, callbacks, appData, component); if (err != OMX_ErrorNone) { return err; } mPluginByInstance.add(*component, plugin); return err; }
在SoftOMXPlugin.cpp中,增加一行
static const struct { const char *mName; const char *mLibNameSuffix; const char *mRole; } kComponents[] = { { "OMX.google.aac.decoder", "aacdec", "audio_decoder.aac" }, { "OMX.my.aac", "aac_my", "audio/mp4a-latm" },
然后实现库文件libstagefright_aac_my.so,在其中实现接口函数SoftOMXComponent *(*CreateSoftOMXComponentFunc)(const char *, const OMX_CALLBACKTYPE *, OMX_PTR, OMX_COMPONENTTYPE **);。
方法2:
实现OMXPluginBase接口及函数OMXPluginBase *(*CreateOMXPluginFunc)(),并在media_codecs.xml中加入对应描述。
struct OMXPluginBase { OMXPluginBase() {} virtual ~OMXPluginBase() {} virtual OMX_ERRORTYPE makeComponentInstance( const char *name, const OMX_CALLBACKTYPE *callbacks, OMX_PTR appData, OMX_COMPONENTTYPE **component) = 0; virtual OMX_ERRORTYPE destroyComponentInstance( OMX_COMPONENTTYPE *component) = 0; virtual OMX_ERRORTYPE enumerateComponents( OMX_STRING name, size_t size, OMX_U32 index) = 0; virtual OMX_ERRORTYPE getRolesOfComponent( const char *name, Vector<String8> *roles) = 0; private: OMXPluginBase(const OMXPluginBase &); OMXPluginBase &operator=(const OMXPluginBase &); };
方法3:
实现一整套NuPlayer机制+OMX Codec