其实就一句话:GPU编解码往往是有损的。这就是刻意的性能优化导致的画质下降,而不是意外产生的损失。
所以用GPU编解码基本相当于牺牲画质换取效率。用CPU编解码就相当于牺牲效率换取画质。
首先要问题搞清楚:
首先 GPU Shader 也是支持整数运算的. RGB/YUV 的转换损失方面, 只要转换不存在于单向的误差, 也不会产生特别明显的偏色问题, 更不用说人眼可见的画质损失通常来自于二次编码.
回到正题, 编码技术的大头还是在 IPB 帧决策、运动分析这样的分析类过程上.
从硬件编码器的实现可以看到, 预测/分析部分有多大的占比.
至于为什么说 CPU 做预测、分析是有优势的, 主要还是在于
这就是为什么很多 CPU 编码测试里, 核心多不一定跑得更快, 因为画面分析/IPB决策是一个相对串行的任务. 纯粹比较速率的话需要看多个方面.
通常在低码率下, CPU 编码+Slow Profile 可以实现更好的画质. 而不同的硬件编码器有各自擅长的场景, 比如 NVENC 在低带宽游戏编码表现上好于 VCN 和 QuickSync.
当然聊到这个就很复杂了, 具体可以去看 YouTube 上针对不同方案下的各种场景/带宽的 VMAF 评测.
如果从实际用途看, 一般游戏玩家肯定不会选择 CPU 或者 Shader 编码, 因为这两个都是游戏运行时高度紧张的资源, 他俩运行起来和游戏帧率完全过不去. 所以通常在没有第二台直播机的情况下, NVENC 是最常用的选择.(顺带可以避免掉画面回传对带宽的影响).
而且不管是 NV 自己还是第三方的测试, NVENC 的 H264/HEVC 经常和 x264 的 slow 打得有来有回, 更不用说吊打 AMD 的老 VCN 了.
但是对于互联网流媒体公司, CPU 编码则有其优势.
首先 CPU 这种资源更加弹性, 而视频硬件编码器到现在为止普遍和 GPU 绑定, 虽然市面上 Intel/Xilinx 都有硬件编码解决方案, 但是这种目前还是服务特殊场景(比如超低延迟游戏直播), 而且 CPU 编码算法都是开源的, 意味着互联网公司可以针对不同场景(比如直播带货、游戏直播、影视点播)进行优化. 以及和分发做更深度的整合.
特别要说明的就比如最近开始流行的 Dolby Vision 8.4 元数据, 这里就涉及到对画面亮度的分析, 从而输出元数据, 优化不同播放介质的 HDR 表现.
商业的 DV 8.4 HEVC 编码器目前就是用 CPU 进行编码的, 主要目的就是为了最大化点播场景下的视频质量.
而直播带货类编码器还会加入视频后处理/降噪, 游戏直播甚至有加入超分提升画面观感, 这些弹性较大的功能通常会考虑用 CPU+GPU 实现.
也有为了追求可编程性下的超低延迟, 选择 Xilinx 的 FPGA 硬件采集+编码方案
就算用CUDA Encoder而不是NVENC,显卡输出画质同码率下也不如纯CPU
主要问题在于batchsize
视频编码要尽可能优化效率,那就要尽可能深的向前后扫描变化不大的部分,扫描复杂度越高,扫描范围越大,耗时也就越长
而编码器的多核优化,本质上是把不同的帧分配给了不同的核心
那么这就产生了两个问题,一个是GPU单个流水线的性能肯定是不如CPU单核的,另一个是显存容量非常有限但GPU流水线非常多
我们都知道,这种把不同部分分配给不同核心的多核优化思路,核心越多占用内存越大,就好比7zip,1线程和4线程内存消耗就有差别
那么现在GPU流水线那么多,比如有2560流水线,却只有8G显存,假设2560流水线全部工作,每个流水线能分配到的显存就仅有最多3.2M
你说这么点显存能干多少活?
所以GPU编码往往采取非常小的batchsize,不但编码扫描深度小,而且甚至可能会把一个画面分成n个部分分给每个流水线,比如一个1600x900的视频,他可以分为16个400x225的画面送入16个流水线
batchsize越大,扫描的范围越大,必然可以用更低的码率实现同样的画质,而CPU编码较大的batchsize决定了画质较好,尤其在高分辨率视频上非常明显
我们不妨举个极端一点的例子,一个完全纯白的60帧视频。如果是CPU来实现,由于单线程可以轻松吃掉2g+的内存,可以扫描整个画面前后1秒的范围,所以最后得到的编码结果就是“全部纯白,60帧”,这个体积显然是非常小的。但如果是GPU编码,由于每条流水线能分到20m都算万幸(目前显存最大的A100,80g显存6912流水线,平均到每流水线也只有11.8m),可别忘了在显存里塞的可是完全无损未压缩的画面,20m只能存放400x225 10bit下的60帧,所以每个流水线输出的就是“在这个400x225范围内,全部纯白,60帧”,最后把数个这样的结果拼起来才得到完整视频,那么这个视频的体积就是CPU编码的数倍。
那么,我们有没有办法结合CPU的高质量和GPU的高速度呢?其实是完全可以的。如果我们使用2pass编码,第一轮使用GPU快处理用于收集信息,第二轮交给CPU生成最终流,那么比直接使用CPU速度更快(profile引导下的编码肯定是更快的),质量又远超GPU编码(因为最终流由CPU生成)
当然,2pass有个非常致命的问题,没有实时性,不适应于直播流,这也是目前直播普遍码率高而画质差的原因,直播不能容忍编码延迟
当然,目前的GPU编码很少有能完全利用流水线的,表现为大部分时候显卡负载都上不去,但尽管如此,GPU编码对显存的需求仍然只能用恐怖形容,x264使用opencl加速(而非纯GPU编码)1080p视频就需要近2g显存消耗,却只能占用3060大约10%性能,换句话说就是只有10%左右流水线在工作。
题主的答案可以分成两部分~
首先,视频画质和软解、硬解并无关系,和到底用CPU硬解还是GPU硬解也没关系。
有关系的你在编码时设置的参数,最常见的就是码率设置成多高。
另外还有YUV设置,比如设置成4:4:4画质的色彩就要好于4:2:0。
此外还有采用的是CBR还是VBR,VBR是哪种算法。
在参数设置相同、采取的补偿算法相同的前提的前提下,用GPU硬解和用CPU软解的结果都是一样的,只不过后者的功耗/发热会很大。
其次,GPU不一定都有完整的视频硬件编解码功能,速度也不一定快。
主要原因之一,是一向以阉割刀法著称的老黄,对自家GPU内编解码电路模块ASIC,也采取了阉割手法。N厂的低端GPU和早期陈旧架构GPU上,负责编解码NVENC/ENDEC运算模块(ASIC)这部分功能是不全。
Kepler更早的Fermi esla等陈旧架构GPU,受当时技术发展、技术应用、市场普及程度等方面的限制,即便是其中的高端GPU,也没有对H265的硬件编解码电路模块。
比如H264和H265这两种格式,PASCAL架构里低端的GT1030完全屏蔽了硬件编解码模块,相同架构的GTX1050才打开该模块。
2012年发布的Kepler架构(主要是GTX680、660等)只支持H264、YUV4:2:0下的硬件编解码。
MAXWELL结构在2014年发布,最早的GTX750/750TI支持H264、YUV4:4:4,不支持压缩率更高的H265。之后同架构的GTX980/960系列开始支持H265、YUV4:2:0。
turing架构的GTX1060和第一代RTX2000系列,进一步支持到H265、YUV4:4:4。
另外,N家的笔记本GPU,也普遍阉割CUDA数量和阉割NVENC/ENDEC的情况。
另外要说的,现在普通用户在使用中,已经基本不会遇到纯粹的软编解码环境了。
因为INTEL的CPU自带自家的编解码电路模块QSV和MFX。AMD的CPUAPU独显,也有自家的UVD/VCE编解码模块。你的电脑里即便没有A/N厂的独显,就用I/A两家的CUP,照样也是硬件编解码。笔记本PC也不必担心,虽然N家的笔记本独显还是大肆阉割,但是intel的笔记本CPU不会屏蔽自家QSV和MFX模块。当用户用笔记本进行视频编解码操作,只要是intel的笔记本CPU,都是硬解。
当然I厂的技术水平和支持的格式有区别。比如INTEL从2014年发布Braswell架构开始支持H265,但2014年之前的几代CPU只支持H264格式。
不是“真实”的画质降低,而是这些编码器实现没有能力做深度压缩,或者说,同样的画质需要消耗高得多的存储空间。
视频编码是一种很特别的东西:压缩格式实际上只是规定了存储的内容的格式,至于你如何生成这些存储的内容,那就是各显神通,具有极大的灵活性。举个最简单的例子,我一点都不做压缩,就每帧原样存进去,也是能够符合压缩格式的,但是显然码率会高到无法直视。
那么视频压缩在干什么?实际上是“大家来找茬”:尽量找到帧间、帧内的重复的地方,然后把差异的地方剔出来单独表示、处理。什么决定了压缩的程度呢?主要是:
问题中的差异其实基本都在第一点上面。压缩算法的实现,主要是三类:
第一种的编程灵活性最高,因为CPU的特性就是可以灵活处理逻辑,所以可以编写非常细腻的找茬过程,把茬都扣出来。
第二种的编程灵活性比较低,因为GPU的通用单元都是智障,你加个if分支都会增加一堆代价,只能尽量执行一大堆相同的操作,显然找茬过程不能太细腻。但是GPU的运算器极多,所以通常比CPU快。
第三种根本不可编程,电路是焊死的只能执行几个固定的找茬算法。但是专用电路永远比通用处理器的效率要高。
任何机械传动装置都是有间隙的,这种间隙在运动中的累积会导致运动误差,体现在汽车转向系统中的表现就是始终无法与道路保持绝对平行,如果不加修正就会越跑越偏,所以行驶中驾驶员必须要随时修正方向。
车况良好的车,行驶中方向偏移是很少的。比如我的车,在直道上正中间行驶时,我可以百米以上不扶方向盘而车不会偏到距离车道线20cm之内。
除转向系统之外,轮胎气压及其它一些因素也会引起车辆跑偏加大。