如何在 ffmpeg 中使用带有 nvenc 的 CRF 编码?

hon*_*cwb 29 ffmpeg video-encoding

这是我当前将视频 (1080p) 大小从 2GB 调整到 300MB 的命令,但这需要很多时间:

mkdir newfiles  
for %%a in ("*.mp4") do ffmpeg -i "%%a" -c:v  libx264 -preset slow -crf 21 -c:a aac -b:a 128k -vf scale=678:-2 "newfiles\%%~na.mp4"  
pause
Run Code Online (Sandbox Code Playgroud)

我用我的 NVIDIA GTX1070 尝试了 nvenc:

mkdir newfiles  
for %%a in ("*.mp4") do ffmpeg -i "%%a" -c:v h264_nvenc -preset slow -c:a aac -b:a 128k -vf scale=678:-2 "newfiles\%%~na.mp4"  
pause
Run Code Online (Sandbox Code Playgroud)

输出大小始终为 3?还是5?原始大小 - nvenc 不使用-crf.

那么我如何使用 nvenc 和 ffmpeg 来转换/调整高质量和小尺寸的视频?我应该使用 GPU 进行编码吗?

Den*_*gai 43

对于基于 CRF 的编码,假设您使用的是最新版本(目前),请将以下代码段中的以下参数传递给 FFmpeg:

-c:v h264_nvenc -preset:v p7 -tune:v hq -rc:v vbr -cq:v 19 -b:v 0 -profile:v high
Run Code Online (Sandbox Code Playgroud)

固定的 CQ 值 19 是推荐的设置,因为它在视觉上与 0 相同,但保留了对文件大小的良好压缩权衡。有关CRF 功能的更多信息,请参阅这篇文章

请注意,-cq比例是对数的,这意味着 0 基本上是无损的,而 51 将是绝对最差的。

通过添加B 帧等选项可以进一步提高质量(最多限制为 3 个,这需要 H.264 主配置文件及更高版本)。

基线配置文件不支持 B 帧。要启用 B 帧,请传递-bf {uint}给视频编码器,这样-bf:v 4将导致编码器使用 4 个 B 帧,编码器可以通过私有编解码器选项启用前瞻来动态调整-rc-lookahead:v n,其中n范围介于32-40。

这里的关键部分是-cq:v 19-rc:v vbr参数,它们允许您在 VBR 速率控制中使用恒定质量模式调整编码器,同时坚持 CRF 值 19。

现在,关于 NVENC 的小笔记,并调整它以获得高质量的编码:

与任何其他基于硬件的编码器一样,NVENC 有几个限制,特别是对于 HEVC,以下是已知的限制:

  1. 关于帕斯卡:

对于 HEVC 编码,以下限制适用:

  • 不支持大于 32 的 CTU 大小。
  • 也不支持 HEVC 中的 B 帧。
  • NVENC 编码器支持的纹理格式限制了编码器可以使用的颜色空间。目前,我们支持 4:2:0(8 位)和 4:4:4(10 位)。不支持 4:2:2 10 位等无关格式。这将影响一些需要此类色彩空间的工作流程。
  • 前瞻控制也仅限于 32 帧。您可能需要查看社论以了解更多详细信息。

图灵拥有 Pascal 可用的所有增强功能,增加了对 HEVC 的 B 帧支持以及使用 B 帧作为参考的能力。有关此功能的示例,请参阅答案。

  1. 在 Maxwell Gen 2(GM200x 系列 GPU)上:

HEVC 编码缺少以下功能:

此处对 Maxwell 的影响是,由于缺少前瞻功能和自适应样本偏移 (SAO) 循环过滤功能,在受限比特率下使用 HEVC 的运动量大的场景可能会出现伪影(块状)。Pascal 和 Turing 在此功能上有所改进,但根据构建视频编码器的 SDK 版本,并非所有功能都可用。

例如,Pascal 上 H.264 编码的加权预测模式需要 NVENC SDK 8.0x 及更高版本,并且该编码模式也会禁用 B 帧支持。同样,运行 Nvidia Performance Primitives (NPP) 的基于硬件的缩放器与 NVENC 的组合可能会以缩放伪像为代价引入视频缩放应用程序的性能改进,特别是对于升级的内容。由于 NPP 的缩放功能在 GPU 上的 CUDA 内核之外运行,同样也会影响视频编码管道,因此,应逐案分析由额外负载引入的性能影响,以确定性能质量取舍是可以接受的。

记住这一点:基于硬件的编码器提供的定制化程度总是比基于软件的同等实现要少,因此,您的里程和可接受的输出质量总是会有所不同。

使用 FFmpeg 中当前的 NVENC 编码器包装器实现,请注意,现在可以使用可调参数覆盖有效预设,具体取决于目标工作负载。看到上这是如何实现的答案,在上面给出的例子,如图所示。

供您参考:

使用 FFmpeg,您始终可以通过以下方式参考编码器的自定义设置:

ffmpeg -h encoder {encoder-name}
Run Code Online (Sandbox Code Playgroud)

因此,对于基于 NVENC 的编码器,您可以运行:

ffmpeg -h encoder=hevc_nvenc

ffmpeg -h encoder=h264_nvenc
Run Code Online (Sandbox Code Playgroud)

您还可以通过运行以下命令查看所有基于 NVENC 的编码器和基于 NPP 的缩放器(如果这样构建):

for i in encoders decoders filters; do
    echo $i:; ffmpeg -hide_banner -${i} | egrep -i "npp|cuvid|nvenc|cuda"
done
Run Code Online (Sandbox Code Playgroud)

我的测试台上的示例输出:

encoders:
 V..... h264_nvenc           NVIDIA NVENC H.264 encoder (codec h264)
 V..... nvenc                NVIDIA NVENC H.264 encoder (codec h264)
 V..... nvenc_h264           NVIDIA NVENC H.264 encoder (codec h264)
 V..... nvenc_hevc           NVIDIA NVENC hevc encoder (codec hevc)
 V..... hevc_nvenc           NVIDIA NVENC hevc encoder (codec hevc)
decoders:
 V..... h263_cuvid           Nvidia CUVID H263 decoder (codec h263)
 V..... h264_cuvid           Nvidia CUVID H264 decoder (codec h264)
 V..... hevc_cuvid           Nvidia CUVID HEVC decoder (codec hevc)
 V..... mjpeg_cuvid          Nvidia CUVID MJPEG decoder (codec mjpeg)
 V..... mpeg1_cuvid          Nvidia CUVID MPEG1VIDEO decoder (codec mpeg1video)
 V..... mpeg2_cuvid          Nvidia CUVID MPEG2VIDEO decoder (codec mpeg2video)
 V..... mpeg4_cuvid          Nvidia CUVID MPEG4 decoder (codec mpeg4)
 V..... vc1_cuvid            Nvidia CUVID VC1 decoder (codec vc1)
 V..... vp8_cuvid            Nvidia CUVID VP8 decoder (codec vp8)
 V..... vp9_cuvid            Nvidia CUVID VP9 decoder (codec vp9)
filters:
 ... hwupload_cuda     V->V       Upload a system memory frame to a CUDA device.
 ... scale_npp         V->V       NVIDIA Performance Primitives video scaling and format conversion
Run Code Online (Sandbox Code Playgroud)

  • 很好的答案!nvenc 上的 ffmpeg wiki 有点过时,并且缺乏所有这些信息...如果您有几分钟的时间,如果您可以在那里贡献您的知识,那就太好了:http://trac.ffmpeg.org/wiki/HWAccelIntro (2认同)
  • `vbr_minqp` 现在似乎已被弃用。有点同意这个答案可能会被误解,因为 `h264_nvenc` 没有 CRF 模式。 (2认同)

Ale*_*998 5

我相信我找到了解决方案:

ffmpeg -hwaccel auto -i in.mp4 -c:v h264_nvenc -preset llhq -rc constqp -qp 21 -c:a copy out.mp4
Run Code Online (Sandbox Code Playgroud)

看来 h264_nvenc 使用-qp而不是-crf. 此选项仅在-rc设置为 时有效constqp

  • 不,“-qp”与“-crf”完全不同。 **h264_nvenc** 的 `-qp` 相当于 **libx264** 的 `-qp` (2认同)
  • @Meow 这对我来说已经足够接近了,但很高兴知道存在差异。对于将来可能会看到这一点的人,[此页面](https://slhck.info/video/2017/02/24/crf-guide.html)解释了 CRF 和 QP 之间的区别。 (2认同)

小智 5

对于-crf从libx264替换可以是-cq-qp从h264_nvenc:

-crf 为恒定质量模式选择质量

-cq 在 VBR 速率控制中为恒定质量模式设置目标质量级别(0 到 51,0 表示自动)

-qp 恒定量化参数速率控制方法(从 -1 到 51)(默认 -1)

最快的硬件加速编码方法:

ffmpeg -hwaccel cuvid -c:v h264_cuvid -resize 640x480 -i input.mp4 -c:v h264_nvenc -cq 21 -c:a copy output.mp4
Run Code Online (Sandbox Code Playgroud)

-resize输入分辨率(在硬件中);无需使用--enable-libnppforscale_npp过滤器编译 ffmpeg 。

欲了解更多信息:

ffmpeg -h encoder=h264_nvenc

ffmpeg -h denoder=h264_cuvid
Run Code Online (Sandbox Code Playgroud)


Mat*_*ics 5

我不是这方面的权威,但我做了大量的研究,特别是为了与使用 Nvidia 硬件编码器加速的 HEVC/h.265 视频流文件的原始 rip 相比,以无法区分和透明的压缩方式存档 Bluray rip。我这样做时会很小心,因此在进行任何特定设置之前,我建议测试每部电影的两个特定部分。我选择的两个部分是电影中最黑暗的部分和快动作部分。

我在两个测试中都通过了音频,并且只渲染了大约 1 分钟,原因有几个:前瞻需要规定数量的帧,并且比特率在场景之间波动。这是我使用 FFMPEG 测试从 30 分 00 秒到 31 分 00 秒的 1 分钟视频。

此外,我使用-qp22、23、24 的 HEVC/h.265测试文件。我无法分辨出更低的差异。高于 24 确实开始在黑暗场景或具有发光的场景或从白色到蓝色平滑宏伟的天空中出现色带。

ffmpeg -hwaccel auto -ss 00:30:01 -to 00:31:01 -i input.mkv -map 0:v:0 -map 0:a:0 -map 0:s:0 -c copy -c:v hevc_nvenc -rc constqp -qp 24 -b:v 0K -c:a copy output.mkv
Run Code Online (Sandbox Code Playgroud)

-map 0分别解复用器第一视频,音频和字幕流(字幕虽然在技术上不是甲流,我只是把它,为简单起见),并为它们分配在remuxed文件中的第一个流。其余设置已在本页前面进行了说明,或者可以查找。

注意:
容器必须是 MKV 才能在字幕中重新混合...无论出于何种原因...我就是无法让 MP4 工作。同样,我不是这方面的专业人士,但我从中获得的结果非常好。

在我检查了 1 分钟的测试文件并喜欢我所看到的之后,我继续处理没有-ss 00:30:01 -to 00:31:01. 我建议你看文件的时候,逐帧回放1分钟渲染图。