C++ FFMPEG没有写AVCC盒信息

awr*_*awr 8 c++ video mp4 ffmpeg h.264

我正在尝试使用C++中的FFMPEG API将原始H264编码为mp4容器.一切正常,但AVCC框为空,它返回错误:[iso file]框"avcC"大小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_);
Run Code Online (Sandbox Code Playgroud)

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

作为参考,这里是修复前mp4的字符:.avc1 ...........................8.H ... H. ......................................... YY .... AVCC ... .stts

之后:avc1 .........................€.8.H ...... H ............ .............................. YY ...!avcC.B€(ÿá..gB€(Ú.à. - ...•你好<€.... STTS

awr*_*awr 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();
Run Code Online (Sandbox Code Playgroud)

这导致正确填充 AVCC 框。


小智 5

我的MP4文件中的AVCC框为空也有问题。原来,我是调用CODEC_FLAG_GLOBAL_HEADERAVCodecContext实例上设置标志的。该标志应调用之前设置。avcodec_open2avcodec_open2