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
解决了。所需的数据是 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_HEADER在AVCodecContext实例上设置标志的。该标志应在调用之前设置。avcodec_open2avcodec_open2