Back
Featured image of post FFmpeg 入门与实践 004 - 视频压缩

FFmpeg 入门与实践 004 - 视频压缩

FFmpeg 系列文章第四篇。这篇继续详解视频压缩细节。

FFmpeg 系列文章导航页

上一篇 FFmpeg 入门与实践 003 - 通用压缩方法及音频压缩

图片及视频压缩

YUV 色彩相关

之前讲过,有很多色彩模型。而在有损压缩时,最常用的就是 YUV。具体而言,是 YUV 的一种:

Y,Cb,Cr \text{Y},\text{C}_\text{b},\text{C}_\text{r}

YUV、RGB 互转

规定以下常数:

WR,WG,WB,Umax,Vmax. \begin{aligned} & W_R,W_G,W_B,\\ & U_\text{max}, V_\text{max}. \end{aligned}

其中,WR,WG,WBW_R,W_G,W_B 为分别对应 R,G,BR,G,B 的权重,同时满足 WR+WG+WB=1W_R+W_G+W_B=1. Umax,VmaxU_\text{max}, V_\text{max} 分别为 U,VU,V 色度的最大值。

Y’UV 一般由 RGB (Gamma 矫正过的,而非线性 RGB)计算而得,如下:

Y=WRR+WGG+WBBU=UmaxBY1WB,V=VmaxRY1WR. \begin{aligned} Y'&= W_RR' + W_GG' + W_BB'\\ U &= U_\text{max} \frac{B' - Y'}{1 - W_B}, \\ V &= V_\text{max} \frac{R' - Y'}{1 - W_R}. \end{aligned}

其中,' 号表示 Gamma 矫正。

Y’UV 三个色度的范围分别为 [0,1][0,1], [Umax,Umax][-U_\text{max},U_\text{max}], [Vmax,Vmax][-V_\text{max},V_\text{max}].

简而言之,YY' 定义为 RGB 加权之和,权重是根据人类视锥细胞决定的,所以 WGW_G 往往最大。

等效的颜色矩阵:

[YUV]=[WRWGWBUmaxWR1WBUmaxWG1WBUmaxVmaxVmaxWG1WRVmaxWB1WR][RGB] \begin{bmatrix} Y' \\ U \\ V \end{bmatrix} = \begin{bmatrix} W_R & W_G & W_B \\ -U_\text{max} \cdot \frac{W_R}{1 - W_B} & -U_\text{max} \cdot \frac{W_G}{1 - W_B} & U_\text{max} \\ V_\text{max} & -V_\text{max}\cdot\frac{W_G}{1 - W_R} & -V_\text{max}\cdot\frac{W_B}{1-W_R} \end{bmatrix} \begin{bmatrix} R' \\ G' \\ B' \end{bmatrix}

及其逆:

[RGB]=[101WRVmax1WB(1WB)UmaxWGWR2WRWGVmax11WBUmax0][YUV] \begin{bmatrix} R' \\ G' \\ B' \end{bmatrix}= \begin{bmatrix} 1 & 0 & \frac{1-W_R}{V_\text{max}} \\ 1 & \frac{W_B(1 - W_B)}{U_\text{max}W_G} & \frac{W_R^2-W_R}{W_G V_\text{max}} \\ 1 & \frac{1-W_B}{U_\text{max}} & 0 \end{bmatrix} \begin{bmatrix} Y' \\ U \\ V \end{bmatrix}

BT.490 中,常数定义为:

WR=0.299,WG=1WRWB=0.587,WB=0.114,Umax=0.436,Vmax=0.615. \begin{aligned} W_R &= 0.299, \\ W_G &= 1 - W_R - W_B = 0.587, \\ W_B &= 0.114, \\ U_\text{max} &= 0.436, \\ V_\text{max} &= 0.615. \end{aligned}

可得颜色矩阵为:

[YUV]=[0.2990.5870.1140.147130.288860.4360.6150.514990.10001][RGB] \begin{bmatrix} Y' \\ U \\ V \end{bmatrix} = \begin{bmatrix} 0.299 & 0.587 & 0.114 \\ -0.14713 & -0.28886 & 0.436 \\ 0.615 & -0.51499 & -0.10001 \end{bmatrix} \begin{bmatrix} R' \\ G' \\ B' \end{bmatrix} \\

及其逆:

[RGB]=[101.1398310.394650.5806012.032110][YUV]. \begin{bmatrix} R' \\ G' \\ B' \end{bmatrix} = \begin{bmatrix} 1 & 0 & 1.13983 \\ 1 & -0.39465 & -0.58060 \\ 1 & 2.03211 & 0 \end{bmatrix} \begin{bmatrix} Y' \\ U \\ V \end{bmatrix}.

BT.709 中,常数定义为:

WR=0.2126,WG=1WRWB=0.7152,WB=0.0722,Umax=0.436,Vmax=0.615. \begin{aligned} W_R &= 0.2126, \\ W_G &= 1 - W_R - W_B = 0.7152, \\ W_B &= 0.0722, \\ U_\text{max} &= 0.436, \\ V_\text{max} &= 0.615. \end{aligned}

可得颜色矩阵:

[YUV]=[0.21260.71520.07220.099910.336090.4360.6150.558610.05639][RGB] \begin{bmatrix} Y' \\ U \\ V \end{bmatrix} = \begin{bmatrix} 0.2126 & 0.7152 & 0.0722 \\ -0.09991 & -0.33609 & 0.436 \\ 0.615 & -0.55861 & -0.05639 \end{bmatrix} \begin{bmatrix} R' \\ G' \\ B' \end{bmatrix}

及其逆:

[RGB]=[101.2803310.214820.3805912.127980][YUV] \begin{bmatrix} R' \\ G' \\ B' \end{bmatrix} = \begin{bmatrix} 1 & 0 & 1.28033 \\ 1 & -0.21482 & -0.38059 \\ 1 & 2.12798 & 0 \end{bmatrix} \begin{bmatrix} Y' \\ U \\ V \end{bmatrix}

一般地,YUV 容易和 YCbCr 混淆。主要是 YUV 同时作为分类名(泛指所有类似的颜色系统),和其分类下的项名(具体区别如下所示)。

技术上,YCbCr 的 UmaxU_\text{max}VmaxV_\text{max}12\frac{1}{2};用途上,YUV 针对模拟电视,YCbCr 用于数字电视。

同时,YCbCr 具有 Full Range 和 Video Range 两种。Video Range 的 YY'[16,235][16,235] 间,UUVV[16,240][16,240] 间。

色度抽样

根据人眼对亮度信息最敏感,而对色度信息的敏感度则次之的特点。可使用色度抽样Chroma Subsample)节省开销。

YUV 通道对比

正如上面所说的那样,看到这幅图后,人眼的确对色度通道感知较不明显。

色度抽样,其实就是降低色度的分辨率,让其为原来的 1/21/21/41/4.

YUV 色度抽样

主要就只有这三种模式。其中 4:2:04:2:0 比较特殊,是轮流采样 Cb 和 Cr。其实也不必太在意这之间的区别。这大同小异。总体而言,4:2:04:2:0 业已满足基本视频需要,几乎你能看到的所有视频,都是这个规格。而 4:2:24:2:24:4:44:4:4 则用于更高画质或视频制作。

原来一个 2×22\times2 区域内,有 3×4=123\times4=12 位数字。经过 4:2:04:2:0 采样后,仅剩 66 位数字。压缩率 rr2:12:1.

量化

如上篇文章里所说的,我们可以使用诸如 DCT、FFT、MDCT 之类的正交变换,将空间域转换为频率域。便于处理。

一系列 8x8 图像和其 Y’ DCT 后的对比图

可以看到,信息几乎被集中到了左上角。可以说,左上角是低频信息,而右下角附近的,是高频信息。第 1 - 3 张是渐变图,颜色变化连续且规律,因此几乎所有信息都是低频信息。第四张是加入少量噪点的渐变图,但仍然很规律。第五张的锐利边缘产生了高频信息。而第六张是纯噪点,有很多低频信息。

图像高低频

很显然,DCT 的特性适合压缩。

  1. DCT 产生大量连续的 0,这对熵编码有利。
  2. DCT 后的图像呈频率特征,利于量化压缩。

对于左上角的高数值,常称为 DC 系数,高频部分的数值常称为 AC 系数。(词源直流电和交流电)。

对于解码器,需要使用 IDCT 将 DCT 频率域图像转回空间域。DCT 变换本身是可逆的,但不是无损的。即使不执行额外的操作,也有细微的精度损失。所以对于使用了 DCT 的图像压缩方法,都是有损方法。

JPEG 量化矩阵

JPEG 标准亮度量化矩阵:

[1611101624405161121214192658605514131624405769561417222951878062182237566810910377243555648110411392496478871031211201017292959811211010399] \begin{bmatrix} 16 & 11 & 10 & 16 & 24 & 40 & 51 & 61 \\ 12 & 12 & 14 & 19 & 26 & 58 & 60 & 55 \\ 14 & 13 & 16 & 24 & 40 & 57 & 69 & 56 \\ 14 & 17 & 22 & 29 & 51 & 87 & 80 & 62 \\ 18 & 22 & 37 & 56 & 68 & 109 & 103 & 77 \\ 24 & 35 & 55 & 64 & 81 & 104 & 113 & 92 \\ 49 & 64 & 78 & 87 & 103 & 121 & 120 & 101 \\ 72 & 92 & 95 & 98 & 112 & 110 & 103 & 99 \end{bmatrix}

如何使用这张表?在上一篇文章中,我们讲解了恒定的量化步长。这张表即定义了对频率域数值的量化步长。

稍微复习一下:量化步长越大,精度损失越高,同时压缩率也越高

实际上,这张 8×88\times 8 的矩阵是统计学的结果。不过稍有规律可循:

  1. 总体而言,随着频率降低(越接近右下),量化步长提高。
  2. 对于 DC 系数,可以看到它比周围点的量化步长稍高。这主要是为了将其落回 8Bit8\,\text{Bit}. 这对精度没有太大影响。
  3. 对于最右下角,量化步长却较周围降低了。此举意义在于,让线条更明晰。

JPEG 标准色度量化矩阵:

[17182447999999991821266699999999242656999999999947669999999999999999999999999999999999999999999999999999999999999999999999999999] \begin{bmatrix} 17 & 18 & 24 & 47 & 99 & 99 & 99 & 99 \\ 18 & 21 & 26 & 66 & 99 & 99 & 99 & 99 \\ 24 & 26 & 56 & 99 & 99 & 99 & 99 & 99 \\ 47 & 66 & 99 & 99 & 99 & 99 & 99 & 99 \\ 99 & 99 & 99 & 99 & 99 & 99 & 99 & 99 \\ 99 & 99 & 99 & 99 & 99 & 99 & 99 & 99 \\ 99 & 99 & 99 & 99 & 99 & 99 & 99 & 99 \\ 99 & 99 & 99 & 99 & 99 & 99 & 99 & 99 \end{bmatrix}

和亮度矩阵类似,但色度的复杂度更低。很多低频信息用以 9999 的量化步长,并最终变为 00

几乎所有编码器都有的一个参数叫做:QPQuantization Parameter),或者 QQuality)。此值,则一般控制量化步长。这产生几个效果:

  1. 量化步长以下的的值变多了,即,0 变多了。
  2. 量化粒度变粗。
  3. Huffman 压缩效率提高。
  4. 往往一种压缩算法有一个或多个甜蜜点。(例如 JPEG 为 75。)质量在这一点后出现明显变化。

Zig Zag

DCT 所需资源不小。如果对整张图进行 DCT,未免效率太低。所以图像常被划分为矩形(在 HEVC 等方法中,允许长方形区域存在)。

分块后,需要一个合理的储存方式,而 Zigzag 无疑是合理的。

Zigzag 扫描

显然的,这样扫描有利于同色区块聚集,提高压缩效率。但请注意,仅仅是储存方式是 Zigzag,这不代表 DCT 计算过程必须按此顺序。DCT 计算过程完全可以同步进行。

Zigzag 的每一个分块被称为宏块Macroblock)。

时域压缩

一张图像只不过是多少帧图像之一。单纯地叠加静帧效率太低。

核心思想是:帧和帧之间的运动,是连续的,相邻的帧,大部分都相同。

在极端一点的情况,比如一图流。这样就尤显低效。

IPB 帧

I 帧Intra Frame),又或者说关键帧。它类似一张静态图片,不参考其他任何帧。

P 帧Predicted Frame),即前向参考帧。它参考一个 GOP(稍后解释) 内所解码的所有前项帧。

B 帧Bidirectional Predicted Frame),即双向参考帧,同时参考 GOP 内的前项和后向帧。

仅 I 帧和 P 帧
I 帧、P 帧和 B 帧

可以看出,B 帧的引入让事情复杂了许多。非 I 帧比例越高,资源消耗越高,这是显然的。

所以固然需要将帧分块(和之前一个道理),即分成,GOPGroup of Picture),图像组。GOP 中的第一个 I 帧,称为 IDR 帧Instantaneous Decoding Refresh),当解码器遇到该帧,将清除所有之前帧缓存,并不再参考这之前的帧。

诚然,上述描述仅仅是对基本时域编码的一个高度抽象性描述。可能仅与原始的 MPEG-1 水平相当。

累了,不写了。下回再更。