c++ FFMPEG不写AVCC框信息

C++ FFMPEG not writing AVCC box information

本文关键字:信息 AVCC 不写 FFMPEG c++      更新时间:2023-10-16

我正在尝试使用c++中的FFMPEG API将原始H264编码为mp4容器。这一切都很好,但是AVCC框是空的,它返回错误:[iso file] Box "avcC" size 8无效

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

ffmpeg -i output.mp4 -vcodec copy 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…… .......................................... yy avcC……stt

之后:

avc1 ......................... €.8.H H…… .......................................... yy…! avcC.B€€(丫. . gB (U.a. -•……hI<€…stt

我的MP4文件也有空AVCC框的问题。原来我是在调用avcodec_open2之后在AVCodecContext实例上设置CODEC_FLAG_GLOBAL_HEADER标志。

在调用avcodec_open2之前设置标志。

解决了。所需的数据是AVCC编解码器的SPS和PPS组件。由于原始的H264流是附件b格式,这出现在每个i帧的开始,在NAL单元开始0x00 0x00 0x00 0x01 0x670x00 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框被正确填充。