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

Android MediaCodec生成的H.264数据异常及MP4播放报错求助

问题修复方案

一、先修复H.264裸流基础问题(解决Elecard StreamType未知)

  • 必须保留SPS/PPS参数集:MediaCodec编码启动时会输出标记为BUFFER_FLAG_CODEC_CONFIG的CSD数据(包含SPS和PPS),这是解码器识别H.264流的核心依据。你之前大概率只保存了编码帧数据,漏掉了这部分。要优先写入CSD数据到文件,再处理后续编码帧。
  • 给每个NALU添加起始码:MediaCodec输出的裸NALU不带起始码,而标准H.264流要求每个NALU以0x000001或0x00000001开头。需要在写入每帧数据前手动插入这4字节(或3字节)起始码,否则分析工具和播放器无法正确分割帧,导致流类型识别失败。

二、修复MP4封装问题(解决错误0xc00d36c4)

  • 禁止直接修改文件后缀为MP4:MP4是有严格容器结构的格式,不是把H.264裸流改个后缀就能用。必须用Android的MediaMuxer完成标准封装:
    1. 创建MediaMuxer实例,指定MP4输出路径;
    2. 从MediaCodec的MediaFormat中提取包含CSD-0、CSD-1的配置,添加视频轨道;
    3. 在onOutputBufferAvailable回调中,按顺序将CSD数据和编码帧传给MediaMuxer.writeSampleData,注意每一帧都要传入连续递增的presentationTimeUs时间戳,时间戳异常会直接导致播放器解析失败。
  • 用工具验证封装正确性:如果自行封装的MP4仍有问题,可通过ffmpeg转封装验证:将修复后的H.264裸流执行命令 ffmpeg -i fixed.h264 -c copy valid.mp4 生成标准MP4,再尝试播放,以此排除封装逻辑问题。

三、验证修复结果

  1. 修复后的H.264裸流,用Elecard重新分析,确认StreamType显示为H.264/AVC;
  2. 用MediaMuxer或ffmpeg封装成MP4后,用系统播放器或VLC尝试播放,检查是否还出现0xc00d36c4错误。

代码细节提示

处理MediaCodec输出时,需区分CSD数据和普通帧:

@Override
public void onOutputBufferAvailable(MediaCodec codec, int index, MediaCodec.BufferInfo info) {
    ByteBuffer buffer = codec.getOutputBuffer(index);
    if ((info.flags & MediaCodec.BUFFER_FLAG_CODEC_CONFIG) != 0) {
        // 优先写入CSD数据(SPS/PPS)
        writeToFile(buffer, info.size);
        codec.releaseOutputBuffer(index, false);
        return;
    }
    // 给普通编码帧添加起始码后写入
    byte[] startCode = {0x00, 0x00, 0x00, 0x01};
    FileOutputStream fos = ...;
    fos.write(startCode);
    buffer.position(info.offset);
    buffer.limit(info.offset + info.size);
    byte[] frameData = new byte[buffer.remaining()];
    buffer.get(frameData);
    fos.write(frameData);
    codec.releaseOutputBuffer(index, false);
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 22:57:29