【问题标题】:FFmpeg camera encode h264 mp4 muxing atom avcC is too smallFFmpeg 摄像头编码 h264 mp4 多路复用原子 avcC 太小
【发布时间】:2016-09-13 16:54:41
【问题描述】:

我尝试将 Android 相机预览帧编码为 h264,并将 mux 编码为 mp4 容器。

我可以成功创建 mp4 文件。但 mp4 格式似乎已损坏。

使用ffprobe,出现以下错误。

$ ffprobe o.mp4
[h264 @ 0x209fe50] non-existing PPS 0 referenced
[h264 @ 0x209fe50] decode_slice_header error
[h264 @ 0x209fe50] no frame!
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x209ea60] decoding for stream 0 failed
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x209ea60] Could not find codec parameters for stream 0 (Video: h264 (avc1 / 0x31637661), none, 568x320, 505 kb/s): unspecified pixel format

然后我使用mp4info工具查看信息是否正确。我找到了这个。

$ mp4info o.mp4 
mp4info version 2.0.0
o.mp4:
ReadProperties: atom 'avcC' is too small; overrun at property: configurationVersion (src/mp4atom.cpp,386)
mp4info: can't open o.mp4

通过 hexdump 文件的内容,我得到了这个

$ xxd o.mp4 |grep -A 5 -B 5 avcC
0039170: 6331 0000 0000 0000 0001 0000 0000 0000  c1..............
0039180: 0000 0000 0000 0000 0000 0238 0140 0048  ...........8.@.H
0039190: 0000 0048 0000 0000 0000 0001 0000 0000  ...H............
00391a0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00391b0: 0000 0000 0000 0000 0000 0000 0018 ffff  ................
00391c0: 0000 0008 6176 6343 0000 0020 7374 7473  ....avcC... stts
00391d0: 0000 0000 0000 0002 0000 004f 0000 0ea6  ...........O....
00391e0: 0000 0001 0000 0000 0000 0058 7374 7373  ...........Xstss
00391f0: 0000 0000 0000 0012 0000 0001 0000 0005  ................
0039200: 0000 000a 0000 000f 0000 0014 0000 0019  ................
0039210: 0000 001e 0000 0023 0000 0028 0000 0029  .......#...(...)

如果我没有将全局标头添加到AVCodecContext

if (ofmt_ctx->oformat->flags & AVFMT_GLOBALHEADER) {
    // oc_ctx->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
}

ffprobe可以无误地检测格式,ffplay也可以播放。但是avcC 原子仍然不正确。其他玩家无法播放。

为什么复用器没有写入正确的avcC atom?

我该如何解决?

【问题讨论】:

    标签: android video ffmpeg mp4 h.264


    【解决方案1】:

    您必须在编解码器上下文中设置 extradata 字段。格式参考这里:Possible Locations for Sequence/Picture Parameter Set(s) for H.264 Stream

    【讨论】:

      【解决方案2】:

      解决了。这个问题只出现在新版本的ffmpeg中。

      当调用 ffmpeg api avformat_write_header/av_write_tailer 时,它使用 AVStream->codecpar 中的数据,因为 AVStream->codec 被标记为已弃用。

      而多余的数据是在avcodec_open2之后填充的,所以我需要将多余的数据复制回AVStream->codecpar

      stream->codecpar->extradata = av_malloc(oc_ctx->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
      stream->codecpar->extradata_size = oc_ctx->extradata_size;
      memcpy(stream->codecpar->extradata, oc_ctx->extradata, oc_ctx->extradata_size);
      

      类似的代码sn-p也可以在ffmpeg项目ffmpeg.c中找到

      if (!ost->st->codecpar->extradata && avctx->extradata) {
          ost->st->codecpar->extradata = av_malloc(avctx->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
          if (!ost->st->codecpar->extradata) {
              av_log(NULL, AV_LOG_ERROR, "Could not allocate extradata buffer to copy parser data.\n");
              exit_program(1);
          }    
          ost->st->codecpar->extradata_size = avctx->extradata_size;
          memcpy(ost->st->codecpar->extradata, avctx->extradata, avctx->extradata_size);
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-11-11
        • 2011-12-06
        • 2013-08-12
        • 2016-07-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多