在 c++ 中以可变帧速率使用 FFmpeg 库(不是 libav 分支)以编程方式捕获视频

Posted

技术标签:

【中文标题】在 c++ 中以可变帧速率使用 FFmpeg 库(不是 libav 分支)以编程方式捕获视频【英文标题】:Programmatically capturing video with the FFmpeg libaries (not the libav fork) with variable frame rate in c++ 【发布时间】:2015-04-09 16:24:02 【问题描述】:

我正在使用 c++ 和 OpenGL 开发模拟器,我想添加一些视频捕获功能(此处需要跨平台)。我决定使用 FFmpeg,因为我可以直接将渲染的帧放入视频中。到目前为止一切都很好,但是在 3D 渲染引擎中,您通常远没有恒定的帧速率,我认为在那里保持恒定并不是一个好主意。因此,我试图弄清楚如何使用 FFmpeg 捕获可变帧速率视频,或者如何从模拟器的可变帧速率获得 FFmpeg 中视频的恒定帧速率。有人可以帮我吗?在可变帧率环境中通常如何拍摄视频?

【问题讨论】:

【参考方案1】:

可变帧速率主要是复用阶段的一个问题,因为您的容器(例如好的 ol' AVI)可能不支持 VFR。只要您混合成支持每帧时间戳的格式,就应该没问题。 mkv (matroska) 或 mp4 就是很好的例子。然后,只要在编码/复用期间正确设置了 AVPacket.dts,你应该没问题,你的视频应该是 VFR。

【讨论】:

感谢您的回答!我暂时不会在视频中添加声音,因此混合部分不会是一件难事。我查看了 FFmpeg 示例,但找不到在时间戳和编码视频的方向上做某事的示例。有没有我还没看过的? 可能不会。大多数示例都比这简单得多。在您的帧捕获代码中,只需确保您的时间戳尽可能精确。然后在使用支持 VFR 的多路复用器编写编码帧时,使用这些时间戳设置编码帧的 AVPacket.pts 值。就是这样,它应该在那之后自然而然地工作。 非常感谢您的回答。我意识到必须在我们设置的时间基准中测量时间戳。据我了解,时基取决于我们在设置中设置的帧速率。所以我尝试评论时基设置并尝试使用纯时间戳(经过毫秒或秒),但它说我必须设置帧速率。应该在那里设置什么帧率或如何避免设置它?我使用 mp4 作为容器。 帧率和时基在不同的字段中。编解码器时基位于 AVStream->codec->time_base 中,平均帧速率(即 movenc.c 使用的)位于 AVStream->avg_frame_rate 中。另请注意,AVPacket.pts/fts 的默认时基是 AV_TIME_BASE(毫秒)。

以上是关于在 c++ 中以可变帧速率使用 FFmpeg 库(不是 libav 分支)以编程方式捕获视频的主要内容,如果未能解决你的问题,请参考以下文章

x264编码时基计算

FFmpeg使用动态帧速率转换两个视频 - 重复/丢帧

用 FFmpeg 录制未知帧率的视频

ffmpeg 将 avi 拆分为具有已知帧速率的帧

使用 ffmpeg 改变帧率

从rtsp流式传输视频,帧速率为1 fps