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

如何解决Android平台H264解码器存在的解码延迟过高问题?

Android MediaCodec H264低延迟解码解决方案

Android 平台硬件 MediaCodec 默认会开启多帧缓冲逻辑来提升解码流畅度,针对你使用的无B帧、单帧可独立解码的实时H264流,可通过以下步骤完全解决缓冲延迟问题:

  • 解码器初始化阶段开启低延迟模式
    配置 MediaFormat 时添加低延迟参数,同时提前传入SPS、PPS参数集,避免解码器等待参数集导致首帧延迟:
    MediaFormat format = MediaFormat.createVideoFormat(MediaFormat.MIMETYPE_VIDEO_AVC, 视频宽度, 视频高度);
    // 传入编码端输出的SPS、PPS数据
    format.setByteBuffer("csd-0", ByteBuffer.wrap(spsByteArray));
    format.setByteBuffer("csd-1", ByteBuffer.wrap(ppsByteArray));
    // 开启低延迟解码,Android 7.0及以上系统支持
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
        format.setInteger(MediaFormat.KEY_LOW_LATENCY, 1);
    }
    m_codec.configure(format, 输出Surface, null, 0);
    m_codec.start();
    
  • 修正时间戳参数,避免全0值导致的解码逻辑异常
    你当前代码所有帧的展示时间戳(pts)均传0,会导致解码器无法判断帧输出顺序,强制触发缓冲逻辑。即便不需要音视频同步,也需要设置递增的时间戳,1fps场景下可按每帧递增1000000微秒设置:
    // 定义全局变量记录当前时间戳
    private long currentPts = 0;
    // 每送入一帧更新一次时间戳
    currentPts += 1000000;
    m_codec.queueInputBuffer(inputIndex, 0, frame.length, currentPts, 0);
    
  • 替换不稳定的空NAL填充方案,改用帧推送后轮询输出逻辑
    填充无意义NAL单元的方案容易触发解码器校验错误崩溃,改为单帧送入后多次短超时轮询输出缓冲区的方案,兼容性和稳定性更高,修改后的解码逻辑如下:
    byte[] frame = h264Data.toByteArray();
    // 送入真实H264帧
    int inputIndex = m_codec.dequeueInputBuffer(-1);
    if (inputIndex >= 0) {
        ByteBuffer buffer;
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP){
            buffer = m_codec.getInputBuffer(inputIndex);
        } else {
            ByteBuffer[] bbuf = m_codec.getInputBuffers();
            buffer = bbuf[inputIndex];
        }
        buffer.put(frame);
        // 使用递增的时间戳
        currentPts += 1000000;
        m_codec.queueInputBuffer(inputIndex, 0, frame.length, currentPts, 0);
    }
    // 轮询取解码输出,最多轮询5次,每次超时1ms即可
    MediaCodec.BufferInfo info = new MediaCodec.BufferInfo();
    for (int i = 0; i < 5; i++) {
        int outputIndex = m_codec.dequeueOutputBuffer(info, 1000);
        if (outputIndex >= 0) {
            m_codec.releaseOutputBuffer(outputIndex, true);
            break;
        } else if (outputIndex == MediaCodec.INFO_TRY_AGAIN_LATER || outputIndex == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
            continue;
        }
    }
    
  • 额外优化建议
    编码端每10~30秒插入一个I帧,携带完整SPS、PPS参数集,避免网络抖动或丢帧导致的花屏、解码器卡死问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.14 05:00:05