【问题标题】:Create I Frame out of P and B frames从 P 和 B 帧中创建 I 帧
【发布时间】:2018-10-25 00:42:26
【问题描述】:

我编写了一个基于 FFMpeg 的 C++ 转换器,它可以接收指向 hls-stream 的链接并将其转换为本地 .mp4 视频。到目前为止,一切都很好,转换器就像一个魅力,毫无疑问。

问题:无论我向转换器提供什么输入源,在转换结束时,我只需要接收带有关键帧的视频。由于完美的正向和反向搜索,我需要这样的视频。

众所周知,辅助视频帧(P 和 B)依赖于其所有者帧(I 帧),因为该帧包含全像素图。据此,我们可以通过将它们的数据与它们的 I 帧合并来为每个 P 和 B 帧重新创建一个 I 帧。这就是为什么这样的 ffmpeg 命令 ffmpeg -i video.mp4 output%4d.jpg 有效的原因。

问题:如何实现帧合并算法,以便在最后重新创建仅关键帧的视频?合并AVPackets 的数据有哪些注意事项?

谢谢。

【问题讨论】:

  • 你不能像那样合并 AVPackets。重新编码时,设置keyint为1。
  • 感谢您的回复,@Gyan。您 100% 并且绝对可以通过合并帧数据来重新创建关键帧。也许不合并AVPacket,也许合并AVFrame。我只是不知道确切的方法是什么,这就是我问这个的原因。并且将 keyint 设置为 1 绝对不会产生帧关键帧。
  • ffmpeg 中的 AVFrames 是完全解码的帧,因此没有“关键帧”或其他内容。 AVframe 标志 key_frame 由解码器设置,是历史信息。使用 keyint=1,我得到所有 IDR 帧。使用 x264 编码。
  • 您能解释一下“keyint=1”是什么意思吗?
  • 编码器的私有选项;在使用-x264-params keyint=1 设置的命令行上。在API中,我相信你需要使用av_opt_set;或者,您可以将编解码器上下文中的 gop_size 设置为 1,然后 x264 包装器将获取该值。

标签: c++ video ffmpeg video-streaming video-encoding


【解决方案1】:

您不能“合并”压缩流的 P 和 B 帧(例如,使用 H.264 编解码器)以获得 I 帧。

ffmpeg 的作用

ffmpeg -i video.mp4 output%4d.jpg

正在解码每一帧(因此它需要从一个 I 帧开始,然后解码流中所有后续的 P 和 B 帧),并将它们压缩回 JPEG 并为原始中的每一帧输出一个 JPEG 图像输入流。

如果您想将带有 P/B 帧的输入流转换为仅内部流(带有所有 I 帧),您需要 transcode 流。 这意味着解码原始流中的所有帧并将它们编码回仅内部流。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-02-19
    • 2021-07-02
    • 1970-01-01
    • 2021-08-16
    • 2013-02-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多