使用 libx264 压缩一组图像时,为什么帧速率会影响最终输出大小?

jd2*_*d20 5 ffmpeg h.264 libx264

我正在使用 ffmpeg 使用 libx264 编解码器将一组图像编码为短延时视频。我的第一次尝试以 30 FPS 的速度进行编码,使用:

ffmpeg -r 30 -pattern_type glob -i "*.jpg" -vcodec libx264 -crf 30 -pix_fmt yuv420p output.mp4
Run Code Online (Sandbox Code Playgroud)

如果是 60 帧,则文件大小为 163 KB,长度为 2 秒。然后我意识到我需要让它慢一些,所以我重新运行相同的命令,但将 -r 更改为 2。现在我有一个 30 秒长的文件,但大小跃升至 891 KB!视频质量在视觉上看起来是一样的。

如何以较慢的帧速率进行编码,而不会使最终文件大小膨胀?


笔记:我的一些理论,以及我检查过的东西。首先,为了确保 ffmpeg 不会在较长版本中重复帧,我检查了 I/P/B 计数。30 FPS 文件具有:

[libx264 @ 0x7f9b26001c00] frame I:1     Avg QP:30.67  size: 44649
[libx264 @ 0x7f9b26001c00] frame P:15    Avg QP:31.19  size:  5471
[libx264 @ 0x7f9b26001c00] frame B:44    Avg QP:31.45  size:   767
Run Code Online (Sandbox Code Playgroud)

2 FPS 文件有:

[libx264 @ 0x7fcd32842200] frame I:1     Avg QP:21.29  size: 90138
[libx264 @ 0x7fcd32842200] frame P:15    Avg QP:22.48  size: 33686
[libx264 @ 0x7fcd32842200] frame B:44    Avg QP:26.29  size:  6674
Run Code Online (Sandbox Code Playgroud)

因此,I/P/B 计数相同,但 2 FPS 文件的 QP 低得多。为了抵消这一影响,我尝试增加 2 FPS 文件的 -crf,以获得大约相同的目标大小,但这只会给我一个非常模糊的视频(必须转到 crf=40)。我尝试弄乱 -minrate、-maxrate、-bt,但没有任何帮助。我猜测有一些 x264 编解码器设置与帧速率相关,但我不知所措地试图找出哪一个(根据我的理解,恒定比特率受帧速率影响,但 CRF 不应该受到影响,但也许我误解了它。

Gya*_*yan 5

CRF 模式的目的是在其编码输出中获得并保持一定的质量水平。如果以 25 fps 显示同一组帧,则每帧的持续时间为 40 毫秒,观看者将无法完全理解瞬态特征。像 x264/x265 这样的编码器将更积极地优化这些帧。OTOH,如果以 2 fps 的速度显示,则每个帧的可见时间为半秒,因此在保持感知质量方面就没有什么余地了。

对于 x264,这是实现该逻辑的提交消息。

VFR/帧速率感知速率控制,第 2 部分

MB-tree 和 qcomp 复杂度估计现在在计算中考虑帧的持续时间。这对于视觉优化非常重要,因为持续时间更长的帧本质上在质量方面更重要。在极端测试用例中将 VFR 感知 PSNR 提高了 1-2db,在更普通的 VFR 剪辑(例如重复数据删除的动画剧集)上提高了约 0.5db。

警告:此更改重新定义了 x264 的内部质量测量。由于上述帧持续时间逻辑,x264 现在将根据视频的帧速率缩放其质量。也就是说,--crf X 为 60fps 视频提供的每帧质量低于 30fps 视频。这将使 --crf 比以前更接近恒定的感知质量。此更改的“中心”是 25fps:也就是说,在相同的 CRF 下,低于 25fps 的视频质量将会提高,而高于 25fps 的视频质量将会下降。这个选择完全是任意的。

请注意,要充分利用这一点,x264 必须以正确的帧速率和正确的时间戳对视频进行编码。