我正在使用ffmpeg C API将实时渲染视频编码为mpg和/或mp4(取决于视频的后续使用情况)。当编码为mp4时,一切都很顺利。但是当编码为mpg时,任何播放器都无法播放生成的视频。快速调用ffprobe就可以看出标头丢失了。但这似乎是不可能的,因为我明确地写了它。
这是我在编码任何帧之前编写标题的方式:
// ptr->oc is the AVFormatContext
int error = avformat_write_header(ptr->oc, NULL);
if (error < 0)
{
s_logFile << "Could not write header. Error: " << error << endl;
fprintf(stderr, "Could not write header. Error: '%i'\n", error);
return 1;
}
编写标题时从未出现任何错误。
对于编码,我正在关注the official muxing.c example,所以我设置了CODEC_FLAG_GLOBAL_HEADER标志。我使用CODEC_ID_MPEG2VIDEO(用于视频)和CODEC_ID_MP2(用于音频)。
结果mpg在我使用外部ffmpeg可执行文件进行“编码”时会起作用:“ffmpeg -i ownEncoded.mpg -sameq -y working.mpg”。 所以似乎所有数据都存在,只有标题由于某种原因而丢失......
以下是ffmpeg在编写标题之前/之前报告的唯一内容:
mpeg -------------------
lvl: 24
msg: VBV buffer size not set, muxing may fail
这可能是问题吗?
我想知道这里有什么问题,因为我用完全相同的函数编码mp4,除了在编码为mp4时设置一些特殊值,如qmin,qmax,me_method等。我是否可能必须设置任何特殊值,以便ffmpeg确实正确地写入标题?
答案 0 :(得分:2)
也许您必须为CODEC_FLAG_GLOBAL_HEADER
设置标记AVCodecContext
。
如果outputFormat->oformat->flags & AVFMT_GLOBALHEADER == true
outputFormat
为AVOutputFormat
因此你应该写
if(outputFormat->oformat->flags & AVFMT_GLOBALHEADER)
codec->flags |= CODEC_FLAG_GLOBAL_HEADER;
还需要查看ffmpeg输出,可能还有警告。
答案 1 :(得分:1)
哦,我的!
原来我输错了导致CODEC_ID_MPEG2VIDEO没有正确设置,而是默认使用H264。当然,这在内部效果不佳.mpg。
感谢评论中的提示,这让我再次看到它! :)