参考代码
在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<SoftOMXComponent> 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这个库