type
status
date
slug
summary
category
tags
password
icon
☀️
视频由一张张图片快速播放形成,认识视频前,先认识图片。要认识如何压缩,先认识如何存储。下文将按照这样的思路进行。

图片

一个图像可以视作一个二维矩阵。如果将色彩考虑进来,我们可以做出推广:将这个图像视作一个三维矩阵——多出来的维度用于储存色彩信息。
如果我们选择三原色(红、绿、蓝)代表这些色彩,这就定义了三个平面:第一个是红色平面,第二个是绿色平面,最后一个是蓝色平面。
notion image
我们把这个矩阵里的每一个点称为像素(图像元素)。像素的色彩由三原色的强度(通常用数值表示)表示。例如,一个红色像素是指强度为 0 的绿色,强度为 0 的蓝色和强度最大的红色。粉色像素可以通过三种颜色的组合表示。如果规定强度的取值范围是 0 到 255,红色 255、绿色 192、蓝色 203 则表示粉色。
例如以下几张图片。第一张包含所有颜色平面。剩下的分别是红、绿、蓝色平面(显示为灰调)(译注:颜色强度高的地方显示为亮色,强度低为暗色)。
notion image
我们可以看到,对于最终的成像,红色平面对强度的贡献更多(三个平面最亮的是红色平面),蓝色平面(最后一张图片)的贡献大多只在马里奥的眼睛和他衣服的一部分。所有颜色平面对马里奥的胡子(最暗的部分)均贡献较少。
存储颜色的强度,需要占用一定大小的数据空间,这个大小被称为颜色深度。假如每个颜色(平面)的强度占用 8 bit(取值范围为 0 到 255),那么颜色深度就是 24(8*3)bit,我们还可以推导出我们可以使用 2 的 24 次方种不同的颜色。
图片的另一个属性是分辨率,即一个平面内像素的数量。通常表示成宽*高。
图像或视频还有一个属性是宽高比,它简单地描述了图像或像素的宽度和高度之间的比例关系。
当人们说这个电影或照片是 16:9 时,通常是指显示宽高比(DAR),然而我们也可以有不同形状的单个像素,我们称为像素宽高比(PAR)。
notion image

图片压缩策略

为此,我们可以利用视觉特性:和区分颜色相比,我们区分亮度要更加敏锐。
我们的眼睛对亮度比对颜色更敏感,你可以看看下面的图片自己测试。
如果你看不出左图的方块 A 和方块 B 的颜色是相同的,那么好,是我们的大脑玩了一个小把戏,这让我们更多的去注意光与暗,而不是颜色。右边这里有一个使用同样颜色的连接器,那么我们(的大脑)就能轻易分辨出事实,它们是同样的颜色。
notion image

色彩的数字存储

我们最开始学习的彩色图像的原理使用的是 RGB 模型,但也有其他模型。有一种模型将亮度(光亮)和色度(颜色)分离开,它被称为 YCbCr*。
* 有很多种模型做同样的分离。
这个颜色模型使用 Y 来表示亮度,还有两种颜色通道:Cb(蓝色色度) 和 Cr(红色色度)。YCbCr 可以由 RGB 转换得来,也可以转换回 RGB。使用这个模型我们可以创建拥有完整色彩的图像,如下图。
notion image
YCbCr 和 RGB 之间的转换
有人可能会问,在 不使用绿色(色度) 的情况下,我们如何表现出所有的色彩?
为了回答这个问题,我们将介绍从 RGB 到 YCbCr 的转换。我们将使用 ITU-R 小组*建议的标准 BT.601 中的系数。
第一步是计算亮度,我们将使用 ITU 建议的常量,并替换 RGB 值。
一旦我们有了亮度后,我们就可以拆分颜色(蓝色色度和红色色度):
并且我们也可以使用 YCbCr 转换回来,甚至得到绿色。
*组织和标准在数字视频领域中很常见,它们通常定义什么是标准,例如,什么是 4K?我们应该使用什么帧率?分辨率?颜色模型?

色度子采样

一旦我们能从图像中分离出亮度和色度,我们就可以利用人类视觉系统对亮度比色度更敏感的特点,选择性地剔除信息。色度子采样是一种编码图像时,使色度分辨率低于亮度的技术。
我们应该减少多少色度分辨率呢?已经有一些模式定义了如何处理分辨率和合并(最终的颜色 = Y + Cb + Cr)。
这些模式称为子采样系统,并被表示为 3 部分的比率 - a:x:y,其定义了色度平面的分辨率,与亮度平面上的、分辨率为 a x 2 的小块之间的关系。
  • a 是水平采样参考 (通常是 4),
  • x 是第一行的色度样本数(相对于 a 的水平分辨率),
  • y 是第二行的色度样本数。
存在的一个例外是 4:1:0,其在每个亮度平面分辨率为 4 x 4 的块内提供一个色度样本。
现代编解码器中使用的常用方案是: 4:4:4 (没有子采样), 4:2:2, 4:1:1, 4:2:0, 4:1:0 and 3:1:1。
下图是同一张图片使用几种主要的色度子采样技术进行编码,第一行图像是最终的 YCbCr,而最后一行图像展示了色度的分辨率。这么小的损失确实是一个伟大的胜利。
notion image
如果我们使用 YCbCr 4:2:0 我们能减少一半的大小

视频

现在我们可以将视频定义为在单位时间连续的 n 帧,这可以视作一个新的维度,n 即为帧率,若单位时间为秒,则等同于 FPS (每秒帧数 Frames Per Second)。
播放一段视频每秒所需的数据量就是它的比特率(即常说的码率)。
比特率 = 宽 * 高 * 颜色深度 * 帧每秒
例如,一段每秒 30 帧,每像素 24 bits,分辨率是 480x240 的视频,如果我们不做任何压缩,它将需要 82,944,000 比特每秒或 82.944 Mbps (30x480x240x24)。
比特率几乎恒定时称为恒定比特率(CBR);但它也可以变化,称为可变比特率(VBR)。
这个图形显示了一个受限的 VBR,当帧为黑色时不会花费太多的数据量。
这个图形显示了一个受限的 VBR,当帧为黑色时不会花费太多的数据量。

视频压缩策略

我们认识到,不对视频进行压缩是不行的;一个单独的一小时长的视频,分辨率为 720p 和 30fps 时将需要 278GB*。仅仅使用无损数据压缩算法——如 DEFLATE(被PKZIP, Gzip, 和 PNG 使用)——也无法充分减少视频所需的带宽,我们需要找到其它压缩视频的方法。
*我们使用乘积得出这个数字 1280 x 720 x 24 x 30 x 3600 (宽,高,每像素比特数,fps 和秒数)
  • 利用视觉特性:和区分颜色相比,我们区分亮度要更加敏锐。
  • 时间上的重复:一段视频包含很多只有一点小小改变的图像。
  • 图像内的重复:每一帧也包含很多颜色相同或相似的区域。
其中,视觉特性与上文提到的图片压缩策略相同。如果我们使用 YCbCr 4:2:0 我们能减少一半的大小(139GB),但仍然不够理想。
我们通过将宽、高、颜色深度和 fps 相乘得出这个值。前面我们需要 24 bit,现在我们只需要 12 bit。

视频术语

现在我们进一步消除时间冗余,但在这之前让我们来确定一些基本术语。假设我们一段 30fps 的影片,这是最开始的 4 帧。
notion image
I 帧(可参考,关键帧,帧内编码),是一个自足的帧。它不依靠任何东西来渲染,I 帧与静态图片相似。第一帧通常是 I 帧,但我们将看到 I 帧被定期插入其它类型的帧之间。
notion image
P 帧(预测),利用了一个事实:当前的画面几乎总能使用之前的一帧进行渲染。例如,在第二帧,唯一的改变是球向前移动了。仅仅使用(第二帧)对前一帧的引用和差值,我们就能重建前一帧。
notion image
B 帧(双向预测),如何引用前面和后面的帧去做更好的压缩?!简单地说 B 帧就是这么做的。
notion image
 
这些帧类型用于提供更好的压缩率,我们将在下一章看到这是如何发生的。现在,我们可以想到 I 帧是昂贵的,P 帧是便宜的,最便宜的是 B 帧。
notion image

时间上的重复

让我们探究去除时间上的重复,去除这一类冗余的技术就是帧间预测
我们将尝试花费较少的数据量去编码在时间上连续的 0 号帧和 1 号帧。
我们可以做个减法,我们简单地用 0 号帧减去 1 号帧,得到残差,这样我们就只需要对残差进行编码
notion image
但我们有一个更好的方法来节省数据量。首先,我们将0 号帧 视为一个个分块的集合,然后我们将尝试将 帧 1 和 帧 0 上的块相匹配。我们可以将这看作是运动预测
我们预计那个球会从 x=0, y=25 移动到 x=6, y=26x 和 y 的值就是运动向量进一步节省数据量的方法是,只编码这两者运动向量的差。所以,最终运动向量就是 x=6 (6-0), y=1 (26-25)
实际情况下,这个球会被切成 n 个分区,但处理过程是相同的。
notion image
我们能看到当我们使用运动预测时,编码的数据量少于使用简单的残差帧技术。
notion image

图像内的重复

让我们探究去除图像内空间上的重复,去除这一类冗余的技术就是帧内预测
如果我们分析一个视频里的每一帧,我们会看到有许多区域是相互关联的
下面是一个 I 帧,我们不能使用前面的帧来预测,但我们仍然可以压缩它。我们将编码我们选择的那块红色区域。如果我们看看它的周围,我们可以估计它周围颜色的变化
notion image
我们预测:帧中的颜色在垂直方向上保持一致,这意味着未知像素的颜色与临近的像素相同
我们的预测会出错,所以我们需要先利用这项技术(帧内预测),然后减去实际值,算出残差,得出的矩阵比原始数据更容易压缩。
notion image

视频容器 VS 视频编码器

  • 容器视为包含视频(也很可能包含音频)元数据的包装格式,例如 MP4。
  • 编码器压缩过的视频可以看成是它承载的内容,例如 H.264 编码压缩后的内容。

视频编解码

是什么? 就是用于压缩或解压数字视频的软件或硬件。
为什么? 人们需要在有限带宽或存储空间下提高视频的质量。

怎么做? 

我们接下来要介绍通用视频编解码器背后的主要机制,大多数概念都很实用,并被现代编解码器如 VP9, AV1 和 HEVC 使用。需要注意:我们将简化许多内容。有时我们会使用真实的例子(主要是 H.264)来演示技术。

第一步 - 图片分区

第一步是将帧分成几个分区子分区甚至更多。
通常,编解码器将这些分区组织成切片(或瓦片),宏(或编码树单元)和许多子分区。这些分区的最大大小有所不同,HEVC 设置成 64x64,而 AVC 使用 16x16,但子分区可以达到 4x4 的大小。
notion image

第二步 - 预测

一旦我们有了分区,我们就可以在它们之上做出预测。对于帧间预测,我们需要发送运动向量和残差;至于帧内预测,我们需要发送预测方向和残差

第三步 - 转换

在我们得到残差块(预测分区-真实分区)之后,我们可以用一种方式变换它,这样我们就知道哪些像素我们应该丢弃,还依然能保持整体质量。这个确切的行为有几种变换方式。
尽管有其它的变换方式,但我们重点关注离散余弦变换(DCT)。DCT 的主要功能有:
  • 像素转换为相同大小的频率系数块
  • 压缩能量,更容易消除空间冗余。
  • 可逆的,也意味着你可以还原回像素。

第四步 - 量化

当我们丢弃一些系数时,在最后一步(变换),我们做了一些形式的量化。这一步,我们选择性地剔除信息(有损部分)或者简单来说,我们将量化系数以实现压缩
我们如何量化一个系数块?一个简单的方法是均匀量化,我们取一个块并将其除以单个的值(10),并舍入值。
notion image

第五步 - 熵编码

在我们量化数据(图像块/切片/帧)之后,我们仍然可以以无损的方式来压缩它。有许多方法(算法)可用来压缩数据。我们将简单体验其中几个,你可以阅读这本很棒的书去深入理解:Understanding Compression: Data Compression for Modern Developers

第六步 - 比特流格式

完成所有这些步之后,我们需要将压缩过的帧和内容打包进去。需要明确告知解码器编码定义,如颜色深度,颜色空间,分辨率,预测信息(运动向量,帧内预测方向),档次*,级别*,帧率,帧类型,帧号等等更多信息。

视频压缩回顾

之前我们计算过我们需要 139GB 来保存一个一小时,720p 分辨率和30fps的视频文件,如果我们使用在这里学过的技术,如帧间和帧内预测,转换,量化,熵编码和其它我们能实现——假设我们每像素花费 0.031 bit——同样观感质量的视频,对比 139GB 的存储,只需 367.82MB
 
 
IINA-MacOS 下最强免费播放器2024 有哪些好用的网盘服务
Loading...