0%

新闻资讯

拥抱变化,赋能产业互联时代

基于硬件加速的视频编解码器(三)

2023-07-31

           首先让我们来回顾一下4090的芯片架构,如下图1所示,其中用白框所框选的部分就是硬件编解码单元,其拥有远超CPU的编解码性能。从图中可以看到NVIDIA的编解码单元被命名为NVENC和NVDEC,顾名思义,NVENC就代表编码器,NVDEC就代表解码器。而4090拥有2颗编码单元,1颗解码单元。

未标题-7.png

图1基于AD102的4090芯片架构

            下表1示截取的NVIDIA官方文档的部门显卡的编码单元信息,从表中可以看出相关GeForce显卡型号支持的编码路数为5路,值得说明的是NVIDIA编码路数的限制是由官方软件内部限定的,官方有能力进行更改,而2023年之前GeForce显卡编码路数是被限制为3路的,懂得都懂。从表中还可以看出30系列显卡是第7代NVENC,而40系列是第八代NVENC,第八代支持了AV1编码,且从4070ti开始,高端显卡拥有2颗NVENC。目前40系显卡硬件编码单元支持H.264、H.265和AV1编码,这时候有人可能会提问了,现存的编码格式超过40种,为什么NVIDIA只支持3种,这个问题我们后续来回答。

表1 NVIDIA部分显卡编码单元信息

 BOARD NVENCTotalMax # ofH.264H.264H.264H.265H.265H.265H.265HEVCHEVCAV1
Generation# ofconcurrent(AVCHD)(AVCHD)(AVCHD)(HEVC)(HEVC)(HEVC)(HEVC)10-bitB Frame
NVENCsessionsYUV 4:2:0YUV 4:4:4Lossless4K YUV 4:2:04K YUV 4:4:44K Lossless8ksupportsupport
GeForce GTX 16306th Gen15YESYESYESYESYESYESYESYESNONO
GeForce GTX 1650 GDDR67th Gen15YESYESYESYESYESYESYESYESYESNO
GeForce GTX 1650 SUPER7th Gen15YESYESYESYESYESYESYESYESYESNO
GeForce RTX 30507th Gen15YESYESYESYESYESYESYESYESYESNO
GeForce RTX 30607th Gen15YESYESYESYESYESYESYESYESYESNO
GeForce RTX 30707th Gen15YESYESYESYESYESYESYESYESYESNO
GeForce RTX 30807th Gen15YESYESYESYESYESYESYESYESYESNO
GeForce RTX 30907th Gen15YESYESYESYESYESYESYESYESYESNO
GeForce RTX 3070 Ti7th Gen15YESYESYESYESYESYESYESYESYESNO
GeForce RTX 3080 Ti7th Gen15YESYESYESYESYESYESYESYESYESNO
GeForce RTX 3090 Ti7th Gen15YESYESYESYESYESYESYESYESYESNO
GeForce RTX 40608th Gen15YESYESYESYESYESYESYESYESYESYES
GeForce RTX 4060TI8th Gen15YESYESYESYESYESYESYESYESYESYES
GeForce RTX 40708th Gen15YESYESYESYESYESYESYESYESYESYES
GeForce RTX 4070 Ti8th Gen25YESYESYESYESYESYESYESYESYESYES
GeForce RTX 4080 16GB8th Gen25YESYESYESYESYESYESYESYESYESYES
GeForce RTX 40908th Gen25YESYESYESYESYESYESYESYESYESYES

            下表2截取的是NVIDIA部分显卡解码单元信息,从表中可以看出30系和40系显卡的解码单元只有一颗且没有对解码单元进行芯片迭代,还是使用第五代NVDEC,所以从这里就可以看出30系列和40系列任意一款显卡的解码性能是相同的,从表中还可得出第五代解码器支持的解码格式为MPEG-1、MPEG-2、VC-1、VP8、VP9、H.264、H.265和AV1。

表2 NVIDIA部分显卡解码单元信息

BOARDNVDECTotalMPEG-1MPEG-2VC-1VP8VP9H.264H.265 (HEVC) 4:2:0*H.265 (HEVC) 4:4:4AV1
Generation# of(AVCHD)
NVDEC8 bit10 bit12 bit8 bit10 bit12 bit8 bit10 bit12 bit8 bit10 bit
GeForce GTX 1080 Ti3rd Gen1YESYESYESNOYESYESYESYESYESYESYESNONONONONO
GeForce GTX 16304th Gen1YESYESYESYESYESYESYESYESYESYESYESYESYESYESNONO
GeForce RTX 30505th Gen1YESYESYESYESYESYESYESYESYESYESYESYESYESYESYESYES
GeForce RTX 30605th Gen1YESYESYESYESYESYESYESYESYESYESYESYESYESYESYESYES
GeForce RTX 30705th Gen1YESYESYESYESYESYESYESYESYESYESYESYESYESYESYESYES
GeForce RTX 30805th Gen1YESYESYESYESYESYESYESYESYESYESYESYESYESYESYESYES
GeForce RTX 30905th Gen1YESYESYESYESYESYESYESYESYESYESYESYESYESYESYESYES
GeForce RTX 3060 Ti5th Gen1YESYESYESYESYESYESYESYESYESYESYESYESYESYESYESYES
GeForce RTX 3070 Ti5th Gen1YESYESYESYESYESYESYESYESYESYESYESYESYESYESYESYES
GeForce RTX 3080 Ti5th Gen1YESYESYESYESYESYESYESYESYESYESYESYESYESYESYESYES
GeForce RTX 3090 Ti5th Gen1YESYESYESYESYESYESYESYESYESYESYESYESYESYESYESYES
GeForce RTX 40605th Gen1YESYESYESYESYESYESYESYESYESYESYESYESYESYESYESYES
GeForce RTX 4060TI5th Gen1YESYESYESYESYESYESYESYESYESYESYESYESYESYESYESYES
GeForce RTX 40705th Gen1YESYESYESYESYESYESYESYESYESYESYESYESYESYESYESYES
GeForce RTX 4070 Ti5th Gen1YESYESYESYESYESYESYESYESYESYESYESYESYESYESYESYES
GeForce RTX 4080 16GB5th Gen1YESYESYESYESYESYESYESYESYESYESYESYESYESYESYESYES
GeForce RTX 40905th Gen1YESYESYESYESYESYESYESYESYESYESYESYESYESYESYESYES

            结合上述,以及之前文章的内容,制作了下图2,让大家更好的理解编解码以及转码的流程。其中虚线代表被压缩的数据,颜色代表其对应的编码格式,特定的颜色只能使用其对应颜色的解码器进行解码;黑色的直线代表容器,容器中存放的就是被压缩的数据,且容器只能使用CPU对其解封装;白色的直线代表被解码出来的元数据,即被还原出来的原始数据。4090的解码单元使用的是第5代NVDEC,支持8种解码格式。编码单元使用的是第八代编码芯片,支持3中编码格式,有两颗编码单元,目的是提高编码能力,而解码单元相比30系列没有提升的原因是因为,目前第五代NVDCE的解码能力还是大于两颗第八代NVENC的编码能力,还是有性能溢出。顺带回答一下之前的问题,为什么编码单元只支持3种编码格式,因为这三种已经是目前市面上最优异的编码算法,所以只需要支持这三种就行。那么图中h264_cuvid又是什么意思呢?前面的h264很好理解,cuvid指的是NVIDIA解码器在FFmpeg中的解码器名称,想要调用相应的硬件解码器只要在API中的选择相应的解码器名称就行,NVIDIA的硬件编解码器是作为插件嵌入到FFmpeg中的,这样就方便程序员开发。

未标题-2.png

图2 音视频编解码示意图

            接下来我们将会结合表3内的ffmpeg部分参数,解释说明测试显卡编解码性能的常用的编解码行命令。

表3 ffmpeg部分参数含义

参数

含义

-y

输出直接覆盖同名文件

-vsync 0

每一帧从解码器到编码器,时间戳保持不变

-c:v

选择编解码器

-i

输入的视频流

-s

视频分辨率

-hwaccel cuda -hwaccel_output_format cuda

将视频帧保留在GPU内存中进行转码

解码:

ffmpeg -y -vsync 0 -c:v h264_cuvid -i input.mp4 output.yuv

            ffmpeg是可执行文件的名称,-y参数是存在同名文件时直接覆盖原先文件,-c:v是选择编解码器,这里选用的是nvidia的h264解码器,-i表示为需要输入的视频流,这里因为是解码所以选取的就是一个视频文件,output.yuv是解码生成的文件,其中output是文件名。值得注意的是单独使用解码,是无法发挥解码芯片的性能的,甚至还会被抑制代全部性能的20%,其原因是直接解码生成元数据,生成的文件动辄百来GB,而这些百来GB的数据是要写入到硬盘中保存的,而像SATA或机械硬盘写入速度是远小于解码速度的,因此解码速度要受限于数据写入硬盘的速度。

编码:

ffmpeg -y -vsync 0 -s 1280x720 -i input.yuv -c:v h264_nvenc output.mp4

            和上面的一样只是这里多了一个参数-s,这个参数表示的是使用元数据生成的视频文件的分辨率,指的注意的是我们必须知道元数据的原始分辨率,否者输入了错误的分辨率,生成的视频就会花屏,就像小时候打雷下雨电视没有信号一样。

转码:

ffmpeg -y -hwaccel cuda -hwaccel_output_format cuda -extra_hw_frames 10 -i 1080.mp4 -c:a copy -c:v av1_nvenc -b:v 5M output1.mp4

            转码是在显存中进行的,每解码一帧就会编码一帧,速速嘎嘎快,因此能发挥显卡最大的解码性能,但也不能到100%,因为还是会受限于编码速度,只有编码性能会发挥到100%。指的注意的是在进行解码的时候只需要选用编码器就行,解码器会自动匹配,-b:v参数是用来控制视频的码率的。最后还有值的提的是如果在转码的过程中对视频的分辨率进行调整,编解码单元是不管的,这部分功能是运行在显卡cuda核心上的。