[英]FFmpeg camera encode h264 mp4 muxing atom avcC is too small
I tried to encode Android camera preview frame to h264, and mux to mp4 container. 我试图将Android相机预览帧编码为h264,将mux编码为mp4容器。
I can created mp4 file successfully. 我可以成功创建mp4文件。 But the mp4 format seems corrupted.
但是mp4格式似乎已损坏。
Use the ffprobe
, I got the following error. 使用
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
Then I use mp4info
tool to see if the information is correct. 然后,我使用
mp4info
工具查看信息是否正确。 I found this. 我找到了这个。
$ 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
By hexdump the content of file, I got this 通过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 .......#...(...)
If I didn't add global header to AVCodecContext
, 如果我没有将全局标头添加到
AVCodecContext
,
if (ofmt_ctx->oformat->flags & AVFMT_GLOBALHEADER) {
// oc_ctx->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
}
ffprobe
can detect the format without error, also ffplay
can play it. ffprobe
可以检测格式没有错误,也ffplay
可以玩。 But the avcC
atom still not correct. 但是
avcC
原子仍然不正确。 Other player cannot play it. 其他玩家无法播放。
Why the muxer didn't write the correct avcC
atom? 为什么
avcC
未编写正确的avcC
原子?
How can I solve it? 我该如何解决?
You must set the extradata field in the codec context. 您必须在编解码器上下文中设置extradata字段。 The format is referenced here: Possible Locations for Sequence/Picture Parameter Set(s) for H.264 Stream
此处引用该格式: H.264流的序列/图片参数集的可能位置
Solved. 解决了。 This problem only happened in the new version ffmpeg.
仅在新版本ffmpeg中发生此问题。
When call ffmpeg api avformat_write_header/av_write_tailer
, it uses the data in AVStream->codecpar
since AVStream->codec
was marked deprecated. 调用ffmpeg api
avformat_write_header/av_write_tailer
,由于AVStream->codec
已被标记为已弃用,因此它将使用AVStream->codecpar
的数据。
And the extra data is filled after avcodec_open2
, so I need to copy extra data back to AVStream->codecpar
. 并且在
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);
Similar code snippet also can be found in ffmpeg project ffmpeg.c 在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);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.