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

Android MediaCodec解码初始帧返回INFO_OUTPT_FORMAT_CHNAGED无法渲染如何处理

问题根因
  • dequeueOutputBuffer返回的负值为状态通知,不是合法的输出缓冲区索引,当前代码未做判断直接传入releaseOutputBuffer会抛出异常,导致前两次解码调用直接失败,无法正常输出首帧
  • INFO_OUTPUT_FORMAT_CHANGED(返回值-2)代表解码器输出格式发生变更,需要确认新格式后才能继续后续解码流程
  • INFO_OUTPUT_BUFFERS_CHANGED(返回值-3)代表输出缓冲区集合发生变更,低版本Android需要重新获取输出缓冲区,高版本虽已废弃该状态但仍需兼容处理避免报错
  • 代码中注释掉了SPS/PPS的配置逻辑,如果是H.264/H.265这类编码格式,解码器必须拿到SPS/PPS参数才能正常解码:如果是带外传输SPS/PPS就打开注释配置到csd-0/csd-1字段,如果是带内传输就确保送入解码器的第一帧数据携带SPS/PPS头
  • 代码中重复定义了init方法,需要删除冗余的一个
修复后代码

init方法

public void init(int width, int height, Surface surface, byte[] sps, byte[] pps) {
    mPts = 0;
    format = MediaFormat.createVideoFormat(FORMAT, width, height);
    // 带外传输SPS/PPS时打开以下两行配置
    //format.setByteBuffer("csd-0", ByteBuffer.wrap(sps));
    //format.setByteBuffer("csd-1", ByteBuffer.wrap(pps));
    mDecoder.configure(format, surface, null, 0);
    mDecoder.start();
}

decodeSample方法

public void decodeSample(byte[] data) {
    try {
        Log.e(TAG, Arrays.toString(data));
        int index = mDecoder.dequeueInputBuffer(TIMEOUT);
        Log.e(TAG, String.valueOf(index));

        if (index >= 0) {
            ByteBuffer buffer = mDecoder.getInputBuffer(index);
            if (buffer != null) {
                buffer.clear();
                buffer.put(data, 0, data.length);
                mDecoder.queueInputBuffer(index, 0, data.length, mPts, 0);
            }
        }
        mPts++;

        int outIndex = mDecoder.dequeueOutputBuffer(info, 1000000);
        Log.e(TAG, "decodeSample: " + outIndex);

        // 增加返回值状态判断
        if (outIndex >= 0) {
            // 仅合法索引才调用渲染逻辑
            Log.d("DecodeActivity", "ready to render.....");
            mDecoder.releaseOutputBuffer(outIndex, true);
        } else if (outIndex == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
            // 输出格式变更,可按需获取新格式参数
            MediaFormat newOutputFormat = mDecoder.getOutputFormat();
            Log.d(TAG, "output format changed: " + newOutputFormat);
        } else if (outIndex == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) {
            // 低版本兼容逻辑,Android 5.0+无需额外处理
            Log.d(TAG, "output buffers changed");
        }
    } catch (Exception exception) {
        Log.e(TAG, "Exception*********: " + exception.getMessage());
        exception.printStackTrace();
    }
}
补充说明
  • 建议pts不要使用简单自增,最好填入帧对应的实际时间戳,避免播放速度不符合预期
  • 若解码后仍出现花屏/首帧不显示问题,优先检查送入的第一帧数据是否携带SPS/PPS头,或者configure前是否正确配置了csd-0/csd-1参数

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 14:45:04