2

我正在使用 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;
}

写入标头时永远不会出现任何错误。

对于编码,我遵循官方 muxing.c 示例,所以我设置了 CODEC_FLAG_GLOBAL_HEADER 标志。我使用 CODEC_ID_MPEG2VIDEO(用于视频)和 CODEC_ID_MP2(用于音频)。

当我在一个额外的步骤中使用外部 ffmpeg 可执行文件“编码”它时,结果 mpg 确实有效:"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 真正正确地写入标头?

4

2 回答 2

2

也许你必须CODEC_FLAG_GLOBAL_HEADERAVCodecContext. 需要它以防万一outputFormat->oformat->flags & AVFMT_GLOBALHEADER == true,在outputFormat哪里AVOutputFormat

因此你应该写

if(outputFormat->oformat->flags & AVFMT_GLOBALHEADER) 
  codec->flags |= CODEC_FLAG_GLOBAL_HEADER;

还要看ffmpeg的输出,可能有警告。

于 2012-11-23T08:05:13.473 回答
1

天啊!

原来我有一个错字导致 CODEC_ID_MPEG2VIDEO 设置不正确,而是使用 H264 作为默认值。当然,这在.mpg 中效果不佳。

感谢评论中的提示,让我又看了一遍!:)

于 2012-11-23T09:30:52.950 回答