You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android NDK MediaCodec异步模式回调函数未触发求助

问题根因与修复方案

1. 未向解码器输入AVC数据(核心原因)

解码器启动后处于空闲等待状态,必须主动向其输入AVC码流数据(包含SPS/PPS和编码帧),才会触发onAsyncInputAvailable/onAsyncOutputAvailable等回调。你的代码仅完成了解码器的配置与启动,没有任何输入数据的逻辑,解码器无工作任务,自然不会触发回调。

修复:在AMediaCodec_start之后添加输入数据的逻辑:

// 示例:向解码器输入单帧AVC数据(实际需根据传入的frames jobject解析批量数据)
ssize_t inputBufferIdx = AMediaCodec_dequeueInputBuffer(decoder, 10000); // 超时10ms
if (inputBufferIdx >= 0) {
    uint8_t* inputBuffer = AMediaCodec_getInputBuffer(decoder, inputBufferIdx);
    // 从frames中取出AVC数据,填充到inputBuffer
    size_t dataSize = ...; // 实际数据长度
    memcpy(inputBuffer, avcFrameData, dataSize);
    // 提交输入buffer,时间戳需按实际帧率设置
    AMediaCodec_queueInputBuffer(decoder, inputBufferIdx, 0, dataSize, 0, 0);
}

2. AMediaCodecOnAsyncNotifyCallback内存管理错误

你通过new在堆上创建结构体,但AMediaCodec_setAsyncNotifyCallback接收的是结构体的值拷贝,堆上的结构体未释放会造成内存泄漏;若后续意外释放,还可能导致回调逻辑异常。

修复:直接在栈上声明结构体即可:

AMediaCodecOnAsyncNotifyCallback notifyCallback = {
    [](AMediaCodec *codec, void *userdata, int32_t index) {
        __android_log_print(ANDROID_LOG_ERROR, "Native_Gate", "onAsyncInputAvailable");
    },
    [](AMediaCodec *codec, void *userdata, int32_t index, AMediaCodecBufferInfo *bufferInfo) {
        __android_log_print(ANDROID_LOG_ERROR, "Native_Gate", "onAsyncOutputAvailable");
    },
    [](AMediaCodec *codec, void *userdata, AMediaFormat *format) {
        __android_log_print(ANDROID_LOG_ERROR, "Native_Gate", "onAsyncFormatChanged");
    },
    [](AMediaCodec *codec, void *userdata, media_status_t error, int32_t actionCode, const char *detail) {
        __android_log_print(ANDROID_LOG_ERROR, "Native_Gate", "onAsyncError");
    }
};
status = AMediaCodec_setAsyncNotifyCallback(decoder, notifyCallback, nullptr);

3. 未正确释放资源(潜在问题)

  • 创建的AMediaFormat未调用AMediaFormat_delete(format),会造成内存泄漏,建议在AMediaCodec_configure执行后调用。
  • ANativeWindow不能在函数结束前释放,需在解码器停止(AMediaCodec_stop)并销毁(AMediaCodec_delete)后,再调用ANativeWindow_release(window)。

4. API版本兼容性问题

AMediaCodec_setAsyncNotifyCallback是Android API 26(Android 8.0)才引入的接口,若测试设备系统版本低于8.0,该函数会返回错误,回调无法触发。可通过打印set callback failed的错误码确认,若错误码为-22(MEDIA_ERROR_INVALID_OPERATION),则大概率是API版本不兼容。

修复:如需兼容低版本,需改用同步模式(循环调用dequeueInputBuffer/dequeueOutputBuffer),或通过API版本判断选择异步/同步逻辑。


内容的提问来源于stack exchange,提问作者xufei

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 12:41:01