【问题标题】:FFmpeg: how to use C++ code to change the frame rate of a video file?FFmpeg:如何使用 C++ 代码更改视频文件的帧速率?
【发布时间】:2014-03-27 15:01:12
【问题描述】:

我知道使用 FFmpeg 命令更改视频文件的帧速率会更容易。 但无论如何,如果我想用 C++ 代码来做,并使用 FFmpeg 库,我该怎么做呢?

我想我应该能够在源代码中找到线索。 在继续之前,我希望有一些好的介绍或例子。

【问题讨论】:

    标签: video ffmpeg


    【解决方案1】:

    这很简单,您只需修改视频流的 time_base 即可。对于简单的容器格式,例如 AVI,您只需要在标题中执行此操作。如果您坚持通过 ffmpeg API 执行此操作,则需要遍历输入流中的所有帧,并将它们复制到输出流。

    以上假设您只想更改 FPS(即减慢或加快视频速度)而不丢帧。但是,如果您想在更改 FPS 的同时保持视频播放的原始速度,则需要重新编码视频,即解码和编码每一帧,同时插入额外的帧或删除一些帧。您不能简单地从视频中删除帧 - 例如,当从 30FPS 转换为 15FPS 时,您不能简单地删除每个第 2 帧,因为它可能是一个关键帧,它会破坏之后的所有帧,直到遇到下一个关键帧。同样,您不能在提高 FPS 时简单地复制一帧,因为 P 帧仅适用于它之前的帧,因此复制它会破坏您的视频。为此,我建议查看我的卡拉 OK 歌词编辑器源代码,特别是 video decodingvideo encoding

    【讨论】:

    • 我想要的是你的第二个解释。播放速度是一样的,只是FPS的变化。比如原来的fps是20,我想改成30fps。所以你的意思是我需要解码成帧,并做一些插入(不是简单的算法)来获得 30 fps 的帧。馈送这些帧以编码为视频文件。但是如果我想实时进行,我需要弄清楚要解码多少帧以及要编码多少帧。那么如何同步这两个进程呢? Android MediaCodec 似乎使用 EGL 来帮助两者的同步。
    • 这很容易。假设您从 20FPS 升级到 30FPS,这意味着每解码 20 帧您需要添加 10 帧 - 所以每 20/10 = 2 帧您需要添加一帧。因此,您将计数器从 2 变为 0,每个 encode 帧都会减少该计数器。一旦它达到零,您再次编码相同的帧(但当然增加了 PTS)并再次将计数器设置为 2。所以源帧序列SSSS变成了SSDSSD,其中D是重复帧。
    • 感谢您的意见。虽然现在我不相信答案,但它很有帮助;所以我投票。所以这是我的问题。我认为它会使用采样在特定时间点获得正确的帧。例如,在 20 fps 的视频文件中,第 1 帧、第 2 帧、第 3 帧位于:0/20 秒、1/20 秒、2/20 秒。现在对于 30 fps 的视频文件,帧 a、帧 b、帧 c 应该是:0/30sec、1/30sec、2/30sec。所以对于 1/30sec 的帧,我们应该在 0/20sec 帧和 1/20sec 帧之间使用一些插值。我认为简单地添加一个新框架并不理想。
    猜你喜欢
    • 2013-08-19
    • 2020-05-27
    • 2017-10-28
    • 2020-01-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-26
    • 2017-03-19
    相关资源
    最近更新 更多