8

我正在尝试使用 C++ 中的 FFMPEG API 将原始 H264 编码到 mp4 容器中。一切正常,但是 AVCC 框为空,并返回错误:[iso file] Box "avcC" size 8 invalid

如果我在输出文件上使用命令行工具:

ffmpeg -i output.mp4 -vcodec 复制fixed.mp4

输出文件有效,并且 AVCC 填充了所需的信息。我不知道为什么这个命令行参数有效,但我无法使用 API 产生相同的结果。

我在 C++ 代码中所做的事情(也在函数调用之间做一些事情):

outputFormat_ = av_guess_format( "mp4", NULL, NULL ); //AV_CODEC_H264
formatContext_ = avformat_alloc_context();
formatContext_->oformat = outputFormat_;
...
AVDictionary *opts = NULL;
char tmpstr[50]; sprintf(tmpstr, "%i", muxRate * KILOBYTESTOBYTES);
av_dict_set(&opts, "muxrate", tmpstr, 0);
avformat_write_header( formatContext_, &opts);
av_write_trailer(formatContext_);

这个输出是正确的,除了它缺少 AVCC 信息。手动添加(并相应地修复盒子长度)让我可以很好地播放视频。知道为什么 API 调用没有生成 AVCC 信息吗?

作为参考,这是修复前 mp4 中的字符:

.avc1.......................€.8.H....H........ .............................ÿÿ....avcC....stts

之后:

avc1..............€.8.H......H....... .........................ÿÿ...!avcC.B€(ÿá..gB€(Ú.à.—•. ..hÎ<€..stts

4

2 回答 2

6

我的 MP4 文件也有空 AVCC 盒子的问题。原来我CODEC_FLAG_GLOBAL_HEADERAVCodecContext调用. _ avcodec_open2该标志应在调用之前avcodec_open2设置。

于 2017-02-05T19:15:02.870 回答
5

解决了。所需的数据是 AVCC 编解码器的 SPS 和 PPS 组件。由于原始 H264 流采用附件 b 格式,因此它出现在每个 I 帧的开头,在 NAL 单元中以0x00 0x00 0x00 0x01 0x67和开头0x00 0x00 0x00 0x01 0x68。因此,需要将该信息复制到 AVStream 编解码器的 extradata 字段中:

codecContext = stream->codec;

...

// videoSeqHeader contains the PPS and SPS NAL unit data
codecContext->extradata = (uint8_t*)malloc( sizeof(uint8_t) * videoSeqHeader_.size() );

for( unsigned int index = 0; index < videoSeqHeader_.size(); index++ )
{
    codecContext->extradata[index] = videoSeqHeader_[index];
}

codecContext->extradata_size = (int)videoSeqHeader_.size();

这导致 AVCC 框被正确填充。

于 2013-04-10T01:40:58.437 回答