我有这个命令
ffmpeg -i input.mp4 -vcodec h264_nvenc -rc vbr_hq -cq 19 -rc-lookahead:v 32 -preset slow -profile:v main -c:a copy output.mp4
对于我的一分钟测试视频,它会在大约 5 秒内生成一个大约 82.5 MB 的文件。
我尝试添加使用 B 帧的选项:-bf:v 3
,但它只会增加约 1.5 秒的编码时间,而文件大小不会改变。B 帧的使用已得到确认ffprobe -show_frames output.mp4 | grep "pict_type"
。我遗漏了什么吗?我认为 B 帧应该会减小文件大小。我的显卡是 GeForce GTX 1650 Max-Q,它应该支持它。我的目标是在良好的编码速度下实现视觉无损,所以我使用 GPU 而不是 CPU。文件大小并不是一个大问题,但越小越好。我正在刻录字幕。
为什么使用 B 帧不会减小视频大小?它是否在某种程度上提高了其感知质量(我希望我的设置根本不可能实现)?
几个附加问题:
答案1
在基于硬件的编码器实现中使用 B 帧,特别是 NVENC(无论是 H.264 还是 HEVC 包装器)不会直接影响编码文件的输出大小,其他所有因素保持不变。
B 帧通常会增加处理输出所需的解码器资源,这就是基线配置文件禁用它的原因。
如果您想要明确控制输出大小,则必须根据需要将目标比特率 ( -b:v
)、最大比特率 ( -maxrate:v
) 和缓冲区大小 ( -bufsize:v
) 设置为适当的值。NVENC 的默认值非常高,约为 ~256 kb/s。因此,您必须手动设置上述这些值,或者通过传递 明确取消设置-b:v 0
。
关于速率控制前瞻 (私有选项-rc-lookahead:v
) 的问题,这在与多个 B 帧 (-bf:v n
其中n > 2
) 结合时非常有用。在这种情况下,编码器将在 0 和您指定的 B 帧数量之间动态选择 B 帧的数量。
实际上,B 帧很棒,因为它们可以提高图像质量,但它们会消耗大量比特率,从而对高运动内容的感知质量 (PQ) 产生负面影响。这是直播等某些应用中需要考虑的一个因素。
请注意,任何形式的加权预测都不能与 NVENC 中的 B 帧结合使用,因此在切换任一选项之前,请仔细权衡您的编码要求。
对于您的工作量,您可以考虑以下两种方法(如上所述,有关比特率控制的注意事项):
1. VBR码率控制下的恒定质量模式:
对于-cq
,请注意,当速率控制(通过-rc:v
NVENC 切换)设置为 VBR(可变比特率)及其变体时,这将切换为恒定质量编码模式。它使用的尺度是对数的, 为1
最高质量模式,51
为最低质量模式。 的默认设置0
表示自动。
2.恒定量化参数码率控制方式:
constqp
此模式要求通过私有编解码器选项明确将速率控制模式设置为,rc:v constqp
并且存在参数-qp:v
,有效值从 到0
。这可以通过分别通过和51
设置的最小和最大允许量化值进一步限制。-qmin:v {int}
-qmax:v {int}
在我的测试中,我能够使用上述方法 (2) 获得最佳效果,即设置一个恒定量化器并将速率控制方法选择为constqp
,如下面两个例子所示:
(a). 使用量化值 0:
ffmpeg -y -i dnce.mkv -vf 'hwupload_cuda=0,yadif_cuda=0:-1:0,scale_cuda=w=1920:h=1080' -c:v h264_nvenc -rc:v constqp -tune:v hq -preset:v p7 -qp:v 0 -b:v 0 -c:a copy nv-test-7.ts
(b). 使用量化值 19:
ffmpeg -y -i dnce.mkv -vf 'hwupload_cuda=0,yadif_cuda=0:-1:0,scale_cuda=w=1920:h=1080' -c:v h264_nvenc -rc:v constqp -tune:v hq -preset:v p7 -qp:v 19 -b:v 0 -c:a copy nv-test-8.ts
在这些情况下,QP 为 0 的编码产生了 8.8 GB 的输出,而后者在 QP 为 19 时产生了 1.3GB 的输出文件。在这两种情况下,输出都必须进行去隔行处理。
我得到最令人困惑的结果是使用恒定质量模式,如上文 (1) 所述:
(a)在VBR模式下使用目标质量等级0:
ffmpeg -y -i dnce.mkv -vf 'hwupload_cuda=0,yadif_cuda=0:-1:0,scale_cuda=w=1920:h=1080' -c:v h264_nvenc -rc:v vbr -tune:v hq -preset:v p7 -cq:v 0 -b:v 0 -c:a copy nv-test-3.ts
(b)在VBR模式下使用目标质量等级19:
ffmpeg -y -i dnce.mkv -vf 'hwupload_cuda=0,yadif_cuda=0:-1:0,scale_cuda=w=1920:h=1080' -c:v h264_nvenc -rc:v vbr -tune:v hq -preset:v p7 -cq:v 19 -b:v 0 -c:a copy nv-test-4.ts
在这种情况下,CQ 设置为 0 和 19 的输出大小分别为 797 和 790MB。
您的里程可能会有所不同,这取决于您的输入文件和正在使用的底层多路复用器,因为 FFmpeg 中的每个多路复用器都有不同的开销等。
注意不要混合和匹配参数,就像我之前的回答一样,这会导致观察结果出现偏差,无法经得起进一步的审查。