什么是视频编解码器?

一篇关于视频编解码器如何工作以及这项技术为何对现代媒体行业如此重要的小文章

背景

本文的目的是与朋友讨论媒体软件时产生的:媒体软件的工作原理和重要性。之后,我了解到真正需要的是一篇简短而简单的文章。因此,在这里,我解释了为什么我们需要编解码器,并概述了它们的工作原理。

Image

如此多的编解码器名称   

 AVC,VP8,VP9,HEVC和现代AV1,VVC :这些都是什么?还有为什么这么多呢?  所有这些缩写都是不同的视频编解码器。它们可以分为两类:    ·     版税编解码器(ITU / MPEG):AVC-> HEVC-> VVC  ·     开源/免版税:VP8-> VP9-> AV1    编解码器的比较是另一篇文章的主题,但是在这里,我将分享一些关键事实:  ·     当前流行的编解码器是AVC(H.264)和VP9(用于许多流行的流媒体服务,WebRTC,YouTube,Twitch)  ·     HEVC(H.265)是一项伟大的技术,于2013年起草。尽管效率很高,但由于不确定和Non-FRAND(Fair, Reasonable and Non-Discriminatory)许可条款,HEVC的采用率仍然很低。  ·     AV1是一种现代且免版税的编解码器。第一个稳定版本于2018年3月28日发布。它已被YouTube,Netflix等流行的流媒体服务积极采用。  ·     VVC(H.266)是HEVC的后继产品。它于2020年7月获得批准,有望成为最先进的压缩技术。  如您所见,存在多种共存的编解码器标准,所有这些标准都在不断发展和竞争。

为什么要开发编解码器   

首先,我们必须了解为什么需要编解码器:  如果我们打开摄像机以录制典型的两小时电影而没有任何压缩,我们将得到一个RGB文件。让我们计算一下它的大小:  给定参数:  ·     影片时长:2小时  ·     每秒帧数:30  ·     分辨率:1920x1080  ·     色彩格式:RGB  2 * 3600 * 30 * 1920 * 1080 * 3 = 1343692800000字节  或1.22 TB!您的计算机中的硬盘存储空间有多少TB?  而如果我们使用HEVC压缩有问题的电影,则可以将其大小减小到2.5GB左右,即小500倍!而且这不会改变分辨率或帧频,也不会显着降低质量。

已确定问题。我们该如何解决?

好的,我希望您能看到问题:原始流非常大。由于分辨率,帧速率,长度,效果(如HDR)等的增加,它们只会变得更大。

因此,我们需要一些压缩技术,但是我们该怎么办?从基本理论我们知道压缩有两种类型:

·     无损的

·     有损的

此外,也可以使用不同的颜色格式。

色彩格式

大多数情况下使用明亮/亮度(Bright/luma encoding)编码(.yuv)代替RGB格式**.**

为什么这样?有一项科学研究表明,人眼luma(亮度)比对颜色更敏感。这样我们可以为每个像素节省一些字节。例如,一种流行的编码格式是4:2:0(每个像素1.5字节)-色度分量的水平和垂直分辨率只有亮度分量的一半(摘自Iain Richardson的书《 H.264高级视频压缩标准》)。请记住,这种格式仅用于存储:当您观看电影时,视频卡会将YUV转换为RGB。

无损压缩

让我们模拟无损压缩,看看我们能得到多好的结果:

输入:

·     YUV颜色格式的原始视频文件:vicue_test_1920x1080_420_8_500.yuv

·     大小:1.44 GB(155.520亿字节)

·     帧数:500

我将7zip用于以下设置:

·     格式:7z

·     压缩程度:中

·     压缩方式:LZMA2

·     字典大小:16 MB

·     字节(Word)大小:32

输出:

·     vicue_test_1920x1080_420_8_500.7z

·     大小:301 MB(316626856字节)

·     压缩率几乎为5:1。不理想...

结论:在上面的示例中,压缩率很好(5:1),但我们仍然可以做得更好。

有损压缩:参考测试

现代编码器如何压缩视频文件?

让我们尝试回答这个问题:为了获得有用和可比的结果,我们可以使用ffmpeg使用HEVC编码相同的.yuv:

ffmpeg -f rawvideo -pix_fmt yuv420p -s:v 1920x1080 -r 25 -i vicue_test_1920x1080_420_8_500.yuv -c:v libx265 output.mp4

结果:

  • output.mp4

  • 大小: 12,5 MB (13 168 899 bytes)

  • 压缩比:118:1!

  • Raw log of ffmpeg:

Input #0, rawvideo, from 'vicue_test_1920x1080_420_8_500.yuv':

Duration: 00:00:20.00, start: 0.000000, bitrate: 622080 kb/s

Stream #0:0: Video: rawvideo (I420 / 0x30323449), yuv420p, 1920x1080, 622080 kb/s, 25 tbr, 25 tbn, 25 tbc

Stream mapping:
Stream #0:0 -> #0:0 (rawvideo (native) -> hevc (libx265))

Press [q] to stop, [?] for help

x265 [info]: HEVC encoder version 3.0_Au+7-cb3e172a5f51

x265 [info]: build info [Windows][GCC 8.2.1][64 bit] 8bit+10bit
x265 [info]: using cpu capabilities: MMX2 SSE2Fast LZCNT SSSE3 SSE4.2 AVX FMA3 BMI2 AVX2

x265 [info]: Main profile, Level-4 (Main tier)

x265 [info]: Thread pool created using 8 threads

x265 [info]: Slices                              : 1
x265 [info]: frame threads / pool features : 3 / wpp(17 rows)
x265 [info]: Coding QT: max CU size, min CU size : 64 / 8
x265 [info]: Residual QT: max TU size, max depth : 32 / 1 inter / 1 intra
x265 [info]: ME / range / subpel / merge : hex / 57 / 2 / 2
x265 [info]: Keyframe min / max / scenecut / bias: 25 / 250 / 40 / 5.00
x265 [info]: Lookahead / bframes / badapt : 20 / 4 / 2
x265 [info]: b-pyramid / weightp / weightb : 1 / 1 / 0
x265 [info]: References / ref-limit cu / depth : 3 / on / on
x265 [info]: AQ: mode / str / qg-size / cu-tree : 2 / 1.0 / 32 / 1
x265 [info]: Rate Control / qCompress : CRF-28.0 / 0.60
x265 [info]: tools: rd=3 psy-rd=2.00 rskip signhide tmvp strong-intra-smoothi
x265 [info]: tools: lslices=6 deblock sao
Output #0, mp4, to 'output.mp4':

Metadata:

    encoder         : Lavf58.26.101
Stream #0:0: Video: hevc (libx265) (hev1 / 0x31766568), yuv420p, 1920x1080, q=2-31, 25 fps, 12800 tbn, 25 tbc

Metadata:
encoder : Lavc58.47.102 libx265
frame= 500 fps=5.4 q=-0.0 Lsize= 12860kB time=00:00:19.88 bitrate=5299.3kbit/s speed=0.217x

video:12854kB audio:0kB subtitle:0kB other streams:0kB global headers:2kB muxing overhead: 0.049566%

x265 [info]: frame I:      4, Avg QP:27.84  kb/s: 6871.70
x265 [info]: frame P: 456, Avg QP:30.31 kb/s: 5370.48
x265 [info]: frame B: 40, Avg QP:33.20 kb/s: 3891.26
x265 [info]: Weighted P-Frames: Y:4.8% UV:4.2%
x265 [info]: consecutive B-frames: 91.7% 7.8% 0.4% 0.0% 0.0%encoded 500 frames in 91.77s (5.45 fps), 5264.15 kb/s, Avg QP:30.52

 

Image

图片之间存在一些细微的差异,但是当文件大小减小到12.5 MB时,视觉质量看起来是相同的。这表明了编解码器压缩技术的重要性。

有损压缩:说明

“如果使用有损压缩,就会失去质量。”的确如此,有些技术可以帮助我们实现几乎(或完全)不明显的质量损失。

保存字节的主要技术如下:

·     可以从同一帧中的另一个位置“继承”一帧中的相似元素(称为帧内预测)

·     “继承”的概念相同,但发生在不同的帧之间(帧间预测)

·     量化

对于非常了解Git VCS的人来说,想法是相同的:不保存整个文件,而是仅保存文件的增量(diff)。

 

编码过程

因此,接下来我们看一下该图,该图显示了高级编码过程:

Image

图片2的说明—编码过程:

1.    作为输入,我们有源视频文件,例如扩展名为.yuv的文件。开始编码的时候,我们从视频中获取1帧。每帧又应分为block。对于每个block,我们再进行计算(并行方式):

2.    [parallel]运动估计(ME:Motion estimation)(帧间)-编码器从另一个帧或多个帧中的块中搜索可以“继承”的block

Image

3. [parallel]帧内预测-编码器从同一帧内的block中搜索可以“继承”的block

Image

4.    在计算了运动估计和帧内预测之后,编码器做出决定并选择哪个预测更有利可图(基于自己的标准,将比特预算最小化并将质量最大化)。

5.    从这一步骤开始,我们将处理预测(而不是源图像)。换句话说,预测是该过程的结果,该过程使我们获得的残留物最少。

6.    这剩余的是我们无法预测的所有数据。剩余的条件公式为:source_block — projection_block = residual_block

7.    在这一步,我们的目标是减少残留量。编码器通过像打折。DCT的原理是以最小的系数最大化图像的特性。它具有强大的``能量压缩''特性:大多数信号信息倾向于集中在DCT的几个低频分量中,从而提高了后续量化过程的效率(在大多数情况下,它可以降低质量损失并提高压缩率)。

这是DCT之后矩阵的良好可视化效果:

Image
  1. 量化可用于在应用诸如DCT之类的变换后降低图像数据的精度,并删除诸如接近零的DCT *之类的无关紧要的值(*从H.264 Advanced Video     Compression Standard,Iain Richardson一书中获得)。换句话说,它是值的简单归约:matrix_of_coefficients /     matrix_of_constants。在这一步,视频流获得最大的有损效果。这是该过程的公式示例

quantized_coefficient[i] = round(coefficents[i]/q_step[i])

这里:

·     quantized_coefficient是量化后的系数向量

·     coefficents— DCT之后的系数向量

·     q_step-编解码器规范中的常数矢量(或现代编解码器中的动态值)。

9.    这是编码器中的解码器。每个编码器中都有一个解码器。需要预测以下帧。这些帧应使用已编码块的预测(否则我们将无益),因此这就是编码器需要解码器的原因。

10.  和11。编码器总和:residual*(5)+prediction(9)=reconstructed_frame。结果,编码器将获得几乎源帧,并将其放入解码器图片缓冲区(DPB)中。DPB是固定大小的固定缓冲区,用于存储参考帧的参考帧将用于ME(第2步)。

11.  当frame/block准备就绪时,我们可以使用熵编码算法(例如CABAC)).

结论

如我们所见,编解码器是使用广泛数学算法的复杂技术(像VVC这样的现代编解码器甚至使用从机器学习领域获得的某些元素)。由于有许多领域需要改进和发展,因此它们的开发一直在持续进行。最终,编解码器的发展不断被市场推动,其需求不断增长,例如更高的分辨率(fullhd-4k-8k-16k),360视频,更高的帧速率(30-60)和特殊效果(例如HDR),但是同时具有较小的带宽成本。
Top