
新闻资讯
拥抱变化,赋能产业互联时代
基于硬件加速的视频编解码器(三)
2023-07-31
首先让我们来回顾一下4090的芯片架构,如下图1所示,其中用白框所框选的部分就是硬件编解码单元,其拥有远超CPU的编解码性能。从图中可以看到NVIDIA的编解码单元被命名为NVENC和NVDEC,顾名思义,NVENC就代表编码器,NVDEC就代表解码器。而4090拥有2颗编码单元,1颗解码单元。
图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 | NVENC | Total | Max # of | H.264 | H.264 | H.264 | H.265 | H.265 | H.265 | H.265 | HEVC | HEVC | AV1 |
Generation | # of | concurrent | (AVCHD) | (AVCHD) | (AVCHD) | (HEVC) | (HEVC) | (HEVC) | (HEVC) | 10-bit | B Frame | ||
NVENC | sessions | YUV 4:2:0 | YUV 4:4:4 | Lossless | 4K YUV 4:2:0 | 4K YUV 4:4:4 | 4K Lossless | 8k | support | support | |||
GeForce GTX 1630 | 6th Gen | 1 | 5 | YES | YES | YES | YES | YES | YES | YES | YES | NO | NO |
GeForce GTX 1650 GDDR6 | 7th Gen | 1 | 5 | YES | YES | YES | YES | YES | YES | YES | YES | YES | NO |
GeForce GTX 1650 SUPER | 7th Gen | 1 | 5 | YES | YES | YES | YES | YES | YES | YES | YES | YES | NO |
GeForce RTX 3050 | 7th Gen | 1 | 5 | YES | YES | YES | YES | YES | YES | YES | YES | YES | NO |
GeForce RTX 3060 | 7th Gen | 1 | 5 | YES | YES | YES | YES | YES | YES | YES | YES | YES | NO |
GeForce RTX 3070 | 7th Gen | 1 | 5 | YES | YES | YES | YES | YES | YES | YES | YES | YES | NO |
GeForce RTX 3080 | 7th Gen | 1 | 5 | YES | YES | YES | YES | YES | YES | YES | YES | YES | NO |
GeForce RTX 3090 | 7th Gen | 1 | 5 | YES | YES | YES | YES | YES | YES | YES | YES | YES | NO |
GeForce RTX 3070 Ti | 7th Gen | 1 | 5 | YES | YES | YES | YES | YES | YES | YES | YES | YES | NO |
GeForce RTX 3080 Ti | 7th Gen | 1 | 5 | YES | YES | YES | YES | YES | YES | YES | YES | YES | NO |
GeForce RTX 3090 Ti | 7th Gen | 1 | 5 | YES | YES | YES | YES | YES | YES | YES | YES | YES | NO |
GeForce RTX 4060 | 8th Gen | 1 | 5 | YES | YES | YES | YES | YES | YES | YES | YES | YES | YES |
GeForce RTX 4060TI | 8th Gen | 1 | 5 | YES | YES | YES | YES | YES | YES | YES | YES | YES | YES |
GeForce RTX 4070 | 8th Gen | 1 | 5 | YES | YES | YES | YES | YES | YES | YES | YES | YES | YES |
GeForce RTX 4070 Ti | 8th Gen | 2 | 5 | YES | YES | YES | YES | YES | YES | YES | YES | YES | YES |
GeForce RTX 4080 16GB | 8th Gen | 2 | 5 | YES | YES | YES | YES | YES | YES | YES | YES | YES | YES |
GeForce RTX 4090 | 8th Gen | 2 | 5 | YES | YES | YES | YES | YES | YES | YES | YES | YES | YES |
下表2截取的是NVIDIA部分显卡解码单元信息,从表中可以看出30系和40系显卡的解码单元只有一颗且没有对解码单元进行芯片迭代,还是使用第五代NVDEC,所以从这里就可以看出30系列和40系列任意一款显卡的解码性能是相同的,从表中还可得出第五代解码器支持的解码格式为MPEG-1、MPEG-2、VC-1、VP8、VP9、H.264、H.265和AV1。
表2 NVIDIA部分显卡解码单元信息
BOARD | NVDEC | Total | MPEG-1 | MPEG-2 | VC-1 | VP8 | VP9 | H.264 | H.265 (HEVC) 4:2:0 | *H.265 (HEVC) 4:4:4 | AV1 | |||||||
Generation | # of | (AVCHD) | ||||||||||||||||
NVDEC | 8 bit | 10 bit | 12 bit | 8 bit | 10 bit | 12 bit | 8 bit | 10 bit | 12 bit | 8 bit | 10 bit | |||||||
GeForce GTX 1080 Ti | 3rd Gen | 1 | YES | YES | YES | NO | YES | YES | YES | YES | YES | YES | YES | NO | NO | NO | NO | NO |
GeForce GTX 1630 | 4th Gen | 1 | YES | YES | YES | YES | YES | YES | YES | YES | YES | YES | YES | YES | YES | YES | NO | NO |
GeForce RTX 3050 | 5th Gen | 1 | YES | YES | YES | YES | YES | YES | YES | YES | YES | YES | YES | YES | YES | YES | YES | YES |
GeForce RTX 3060 | 5th Gen | 1 | YES | YES | YES | YES | YES | YES | YES | YES | YES | YES | YES | YES | YES | YES | YES | YES |
GeForce RTX 3070 | 5th Gen | 1 | YES | YES | YES | YES | YES | YES | YES | YES | YES | YES | YES | YES | YES | YES | YES | YES |
GeForce RTX 3080 | 5th Gen | 1 | YES | YES | YES | YES | YES | YES | YES | YES | YES | YES | YES | YES | YES | YES | YES | YES |
GeForce RTX 3090 | 5th Gen | 1 | YES | YES | YES | YES | YES | YES | YES | YES | YES | YES | YES | YES | YES | YES | YES | YES |
GeForce RTX 3060 Ti | 5th Gen | 1 | YES | YES | YES | YES | YES | YES | YES | YES | YES | YES | YES | YES | YES | YES | YES | YES |
GeForce RTX 3070 Ti | 5th Gen | 1 | YES | YES | YES | YES | YES | YES | YES | YES | YES | YES | YES | YES | YES | YES | YES | YES |
GeForce RTX 3080 Ti | 5th Gen | 1 | YES | YES | YES | YES | YES | YES | YES | YES | YES | YES | YES | YES | YES | YES | YES | YES |
GeForce RTX 3090 Ti | 5th Gen | 1 | YES | YES | YES | YES | YES | YES | YES | YES | YES | YES | YES | YES | YES | YES | YES | YES |
GeForce RTX 4060 | 5th Gen | 1 | YES | YES | YES | YES | YES | YES | YES | YES | YES | YES | YES | YES | YES | YES | YES | YES |
GeForce RTX 4060TI | 5th Gen | 1 | YES | YES | YES | YES | YES | YES | YES | YES | YES | YES | YES | YES | YES | YES | YES | YES |
GeForce RTX 4070 | 5th Gen | 1 | YES | YES | YES | YES | YES | YES | YES | YES | YES | YES | YES | YES | YES | YES | YES | YES |
GeForce RTX 4070 Ti | 5th Gen | 1 | YES | YES | YES | YES | YES | YES | YES | YES | YES | YES | YES | YES | YES | YES | YES | YES |
GeForce RTX 4080 16GB | 5th Gen | 1 | YES | YES | YES | YES | YES | YES | YES | YES | YES | YES | YES | YES | YES | YES | YES | YES |
GeForce RTX 4090 | 5th Gen | 1 | YES | YES | YES | YES | YES | YES | YES | YES | YES | YES | YES | YES | YES | YES | YES | YES |
结合上述,以及之前文章的内容,制作了下图2,让大家更好的理解编解码以及转码的流程。其中虚线代表被压缩的数据,颜色代表其对应的编码格式,特定的颜色只能使用其对应颜色的解码器进行解码;黑色的直线代表容器,容器中存放的就是被压缩的数据,且容器只能使用CPU对其解封装;白色的直线代表被解码出来的元数据,即被还原出来的原始数据。4090的解码单元使用的是第5代NVDEC,支持8种解码格式。编码单元使用的是第八代编码芯片,支持3中编码格式,有两颗编码单元,目的是提高编码能力,而解码单元相比30系列没有提升的原因是因为,目前第五代NVDCE的解码能力还是大于两颗第八代NVENC的编码能力,还是有性能溢出。顺带回答一下之前的问题,为什么编码单元只支持3种编码格式,因为这三种已经是目前市面上最优异的编码算法,所以只需要支持这三种就行。那么图中h264_cuvid又是什么意思呢?前面的h264很好理解,cuvid指的是NVIDIA解码器在FFmpeg中的解码器名称,想要调用相应的硬件解码器只要在API中的选择相应的解码器名称就行,NVIDIA的硬件编解码器是作为插件嵌入到FFmpeg中的,这样就方便程序员开发。
图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核心上的。