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

如此多的编解码器名称
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

图片之间存在一些细微的差异,但是当文件大小减小到12.5 MB时,视觉质量看起来是相同的。这表明了编解码器压缩技术的重要性。
有损压缩:说明
“如果使用有损压缩,就会失去质量。”的确如此,有些技术可以帮助我们实现几乎(或完全)不明显的质量损失。
保存字节的主要技术如下:
· 可以从同一帧中的另一个位置“继承”一帧中的相似元素(称为帧内预测)
· “继承”的概念相同,但发生在不同的帧之间(帧间预测)
· 量化
对于非常了解Git VCS的人来说,想法是相同的:不保存整个文件,而是仅保存文件的增量(diff)。
编码过程
因此,接下来我们看一下该图,该图显示了高级编码过程:

图片2的说明—编码过程:
1. 作为输入,我们有源视频文件,例如扩展名为.yuv的文件。开始编码的时候,我们从视频中获取1帧。每帧又应分为block。对于每个block,我们再进行计算(并行方式):
2. [parallel]运动估计(ME:Motion estimation)(帧间)-编码器从另一个帧或多个帧中的块中搜索可以“继承”的block

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

4. 在计算了运动估计和帧内预测之后,编码器做出决定并选择哪个预测更有利可图(基于自己的标准,将比特预算最小化并将质量最大化)。
5. 从这一步骤开始,我们将处理预测(而不是源图像)。换句话说,预测是该过程的结果,该过程使我们获得的残留物最少。
6. 这剩余的是我们无法预测的所有数据。剩余的条件公式为:source_block — projection_block = residual_block
7. 在这一步,我们的目标是减少残留量。编码器通过像打折。DCT的原理是以最小的系数最大化图像的特性。它具有强大的``能量压缩''特性:大多数信号信息倾向于集中在DCT的几个低频分量中,从而提高了后续量化过程的效率(在大多数情况下,它可以降低质量损失并提高压缩率)。
这是DCT之后矩阵的良好可视化效果:

-
量化可用于在应用诸如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)).