Stagefright中增加Codec支持

部署运行你感兴趣的模型镜像


方法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



                

您可能感兴趣的与本文相关的镜像

Qwen-Image

Qwen-Image

图片生成
Qwen

Qwen-Image是阿里云通义千问团队于2025年8月发布的亿参数图像生成基础模型,其最大亮点是强大的复杂文本渲染和精确图像编辑能力,能够生成包含多行、段落级中英文文本的高保真图像

用户使用Android手机看ins时视频画面突然闪黑屏,并重复播放某几帧。 以下时该时间点附近关于codec相关的Android log打印,介绍一下这些代表什么?可能出现该现象的原因是什么? Line 205740: 09-21 16:44:57.102274 14301 28817 W Codec2Client: query -- param skipped: index = 1107298332. Line 205741: 09-21 16:44:57.103281 14301 28817 I CCodecConfig: query failed after returning 21 values (BAD_INDEX) Line 205743: 09-21 16:44:57.106183 14301 28817 W Codec2Client: query -- param skipped: index = 1342179345. Line 205744: 09-21 16:44:57.106350 14301 28817 W Codec2Client: query -- param skipped: index = 2415921170. Line 205745: 09-21 16:44:57.106409 14301 28817 W Codec2Client: query -- param skipped: index = 1610614798. Line 205759: 09-21 16:44:57.123523 1514 2812 E Codec2-ComponentInterface: We have a failed config Line 205760: 09-21 16:44:57.124375 14301 28817 D CCodecBuffers: [c2.android.aac.decoder#217:1D-Output.Impl[N]] converted 0 buffers to array mode of 6 Line 205939: X.6Wj: MediaCodecVideoRenderer error, index=0, format=Format(3204453916387458v, null, null, video/av01, av01.0.08M.08.0.111.01.01.01.0, 2043403, null, [1080, 1920, 30.0, ColorInfo(BT709, Limited range, SDR SMPTE 170M, false, NA, NA)], [-1, -1]), format_supported=YES Line 205978: 09-21 16:44:57.411646 14301 28817 I CCodecConfig: query failed after returning 21 values (BAD_INDEX) Line 205982: 09-21 16:44:57.412664 14301 28817 W Codec2Client: query -- param skipped: index = 1342179345. Line 205983: 09-21 16:44:57.412702 14301 28817 W Codec2Client: query -- param skipped: index = 2415921170. Line 205984: 09-21 16:44:57.412713 14301 28817 W Codec2Client: query -- param skipped: index = 1610614798. Line 206187: 09-21 16:44:57.464375 1893 2525 D OplusTddV2Controller: DynamicTddModeSupported=true mIsSupportAPPEnter=false Wifi24GState=true SoftApEnabled=false WifiP2pConnected=false DBSEnabled=false blueToothState=false isWeakNetworkEnv=false isDynamicTddForceDisabled=false mIsDynamicTddBtCodec=false mScreenOn=true Line 206398: 09-21 16:44:58.077431 14301 28833 W libc : Access denied finding property "vendor.debug.stagefright.mediacodec.trace" Line 206402: 09-21 16:44:58.091300 14301 28839 D CCodecConfig: read media type: audio/mp4a-latm Line 206410: 09-21 16:44:58.117336 14301 28839 I CCodecConfig: query failed after returning 21 values (BAD_INDEX) Line 206411: 09-21 16:44:58.128219 14301 28833 E MediaCodec: Media Quality Service not found. Line 206413: 09-21 16:44:58.136120 14301 28839 W Codec2Client: query -- param skipped: index = 1107298332. Line 206414: 09-21 16:44:58.136862 14301 28839 I CCodecConfig: query failed after returning 21 values (BAD_INDEX) Line 206416: 09-21 16:44:58.140513 14301 28839 W Codec2Client: query -- param skipped: index = 1342179345. Line 206417: 09-21 16:44:58.140585 14301 28839 W Codec2Client: query -- param skipped: index = 2415921170. Line 206418: 09-21 16:44:58.140621 14301 28839 W Codec2Client: query -- param skipped: index = 1610614798.
最新发布
09-29
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值