ESC
输入关键词搜索文章
目录

H.264 视频编码原理详解

图像压缩基础系列 · 第八篇
12 个专题,从数字视频基础到 CABAC 熵编码,系统拆解最广泛使用的视频编码标准
8基础系列
12专题
2003标准发布
引言
为什么是 H.264?

H.264/AVC(Advanced Video Coding)是视频压缩史上应用最广泛的标准。从 2003 年发布至今,它几乎统治了数字视频的每一个场景:流媒体、视频会议、广播电视、监控、蓝光光盘、移动设备……即使在 HEVC 和 AV1 已经成熟的今天,H.264 仍然是兼容性最好的"最大公约数"。

H.264 在 MPEG-2 的基础上提供了约 50% 的压缩效率提升,这并非来自某一个突破性的技术,而是来自一系列精心设计的工具的组合:灵活的宏块划分、多参考帧、1/4 像素运动估计、整数 DCT、环路滤波、CABAC 熵编码……每个工具单独看都不算革命性的,但它们组合在一起,形成了一个高度协调的编码系统。

本篇按 12 个专题系统拆解 H.264 的编码原理,从数字视频的基础概念一直讲到熵编码的细节。这 12 个专题的结构参考了抖音合集"望天空云卷云舒"的 H.264 视频编码原理系列,在此基础上做了学术化和工程化的扩展。

专题一
H.264 概述:标准背景与发展历程
谁制定了 H.264?

H.264 由两个国际标准组织联合制定:

  • ITU-T VCEG(Video Coding Experts Group):国际电信联盟的视频编码专家组
  • ISO/IEC MPEG(Moving Picture Experts Group):国际标准化组织的运动图像专家组

两个组织联合成立了 JVT(Joint Video Team),于 2001 年开始开发,2003 年 5 月正式发布第一版标准。在 ITU-T 体系中称为 H.264,在 ISO/IEC 体系中称为 MPEG-4 Part 10 / AVC(Advanced Video Coding)。

这是两个组织继 H.262/MPEG-2 之后的第二次深度合作。

H.264 的发展历程
时间事件
1998VCEG 开始 H.26L 项目("Long-term"),探索新一代视频编码
2001JVT 成立,合并 VCEG 和 MPEG 的研究成果
2003.05H.264/AVC 第一版正式发布
2004补充 FRExt(Fidelity Range Extensions),支持更高位深和色度采样
2007补充 SVC(Scalable Video Coding),支持可伸缩编码
2009补充 MVC(Multiview Video Coding),支持多视角/3D 视频
H.264 的应用领域

H.264 的应用几乎覆盖了所有数字视频场景:

  • 流媒体:YouTube、Netflix、Bilibili 等平台的早期主力编码格式
  • 视频会议:Zoom、Teams、WebRTC 默认编码
  • 广播电视:DVB-T/T2、ATSC、ISDB 等数字电视标准
  • 监控:安防摄像头标准编码
  • 蓝光光盘:BD-ROM 三种可选编码之一(与 MPEG-2、VC-1 并列)
  • 移动设备:3GPP、iPhone 视频录制
中国的应对:AVS 标准

面对 H.264 的专利授权费用问题,中国自主研发了 AVS(Audio Video coding Standard)系列标准:

  • AVS1(2006):对标 H.264 Baseline/Main Profile,压缩效率相近
  • AVS2(2016):对标 HEVC,面向超高清视频
  • AVS3(2019):对标 VVC,支持 8K 视频

AVS 标准的专利政策更加友好,授权费用远低于 H.264/HEVC。

专题二
数字视频基础知识
什么是数字视频?

数字视频是连续的图像帧序列在数字域的表示。理解数字视频,需要理解以下几个核心概念:

  • 像素(Pixel):图像的最小单位,每个像素有一个亮度值和色度值
  • 分辨率(Resolution):图像的宽高像素数,如 1920×1080
  • 帧率(Frame Rate):每秒显示的帧数,如 24fps、30fps、60fps
  • 位深(Bit Depth):每个像素分量的比特数,如 8-bit(256 级)、10-bit(1024 级)
  • 色彩空间(Color Space):像素值的数学表示方式,如 RGB、YUV
数字视频的表示

一幅数字图像可以表示为二维离散信号 $f(x, y)$,其中 $(x, y)$ 是像素坐标,$f$ 是像素值。

一段数字视频可以表示为三维离散信号 $f(x, y, t)$,其中 $t$ 是时间索引(帧号)。

数字视频基础知识概念图
图 1:数字视频基础知识概念图。从像素、分辨率、帧率到色彩空间的完整知识框架。
采样与量化

模拟视频信号转换为数字视频需要两个步骤:

空间采样(Spatial Sampling)

在水平和垂直方向上对连续的图像进行离散采样,得到像素网格。采样间隔决定了分辨率。

幅度量化(Amplitude Quantization)

将每个像素的连续亮度/色度值映射为离散的整数值。量化精度由位深决定:

位深级数典型应用
8-bit256标准动态范围(SDR)视频
10-bit1024高动态范围(HDR)视频
12-bit4096专业影视制作
PCM 脉冲编码调制(Pulse Code Modulation)
PCM 是什么?

PCM(Pulse Code Modulation,脉冲编码调制)是将模拟信号转换为数字信号的标准方法。它是所有数字音频和视频的基础——从 CD 音频到数字电视,从电话系统到数字摄像机,都使用 PCM 或其变体。

PCM 由 Alec Reeves 于 1937 年发明,是数字通信的奠基性技术之一。

PCM 的三个步骤

PCM 将连续的模拟信号转换为离散的数字码流,包含三个核心步骤:

PCM 脉冲编码调制的三个步骤:采样、量化、编码
图 2:PCM 脉冲编码调制的完整流程。
  • 采样:在时间轴上以固定间隔 $T_s$ 对连续模拟信号 $f(t)$ 进行采样,得到离散样值序列 $f(nT_s)$
  • 量化:将每个样值的连续幅度映射为有限的离散电平(图中为 8 级量化)。
  • 编码:将每个量化电平用二进制码字表示(图中为 3-bit 编码),最终输出数字码流。
  • Step 1:采样(Sampling)

    在时间轴上以固定间隔 $T_s$(采样周期)对连续模拟信号 $f(t)$ 进行采样,得到离散时间信号 $f(nT_s)$

    采样频率 $f_s = 1/T_s$ 必须满足奈奎斯特采样定理(Nyquist Sampling Theorem):

    $$f_s \geq 2 f_{\text{max}}$$

    其中 $f_{\text{max}}$ 是信号的最高频率分量。如果采样频率低于 2 倍最高频率,会发生混叠(Aliasing)——高频分量被错误地重建为低频分量。

    采样频率的实际选择
    • 音频:人耳可听范围 ~20 kHz,CD 使用 44.1 kHz($> 2 \times 20 \text{ kHz}$
    • 视频:空间采样的"采样频率"由分辨率决定。1080p 意味着水平方向每行采样 1920 个点
    Step 2:量化(Quantization)

    将每个采样值的连续幅度映射为有限个离散电平。量化级数 $L$ 由位深 $n$ 决定:

    $$L = 2^n$$

    量化引入了量化误差(Quantization Error):

    $$e_q = f(nT_s) - \hat{f}(nT_s)$$

    其中 $\hat{f}(nT_s)$ 是量化后的值。量化误差是不可逆的——这是有损压缩的根本来源。

    量化信噪比(SQNR)

    对于均匀量化和满幅度正弦信号,量化信噪比约为:

    $$\text{SQNR}_{\text{dB}} \approx 6.02n + 1.76 \text{ dB}$$

    这意味着每增加 1 bit 位深,信噪比提高约 6 dB

    位深量化级数SQNR(理论)
    8-bit256~50 dB
    10-bit1024~62 dB
    12-bit4096~74 dB
    16-bit65536~98 dB(CD 音频)
    量化原理详解

    量化是 PCM 中唯一引入不可逆失真的步骤,也是视频压缩中最重要的概念之一。理解量化原理对于理解后续 H.264 中的 DCT 量化至关重要。

    量化原理:均匀量化与非均匀量化
    图 3:量化原理详解。左上:均匀量化的输入-输出特性——量化间隔 $\Delta$ 恒定,量化误差 $e_q \in [-\Delta/2, \Delta/2]$。右上:非均匀量化——小信号区域量化间隔更小(精度高),大信号区域量化间隔更大(精度低)。下方:量化过程示意——连续样值 $f(nT_s)$ 被映射到最近的量化电平 $y_k$,量化误差为 $e_q = f(nT_s) - y_k$
    均匀量化(Uniform Quantization)

    均匀量化的量化间隔 $\Delta$ 在整个信号范围内保持恒定:

    $$\Delta = \frac{V_{\text{max}} - V_{\text{min}}}{L} = \frac{2V_{\text{max}}}{2^n}$$

    其中 $V_{\text{max}}$ 是信号的最大幅度,$L = 2^n$ 是量化级数。

    量化误差范围:

    $$|e_q| \leq \frac{\Delta}{2}$$

    均匀量化的特点:

    • 优点:实现简单,硬件成本低
    • 缺点:小信号和大信号使用相同的量化间隔,小信号的相对误差更大
    非均匀量化(Non-uniform Quantization)

    非均匀量化根据信号幅度调整量化间隔:

    • 小信号区域:量化间隔更小 → 精度更高
    • 大信号区域:量化间隔更大 → 精度较低

    这与人眼的感知特性一致:人眼对暗部的亮度变化更敏感,对亮部的变化较不敏感。

    实现方式:先对信号做压缩(Compress),再均匀量化,解码时做扩张(Expand)。这种组合称为 Companding(压缩-扩张)。

    标准压缩函数应用
    μ-law(μ 律)$F(x) = \frac{\ln(1+\mux)}{\ln(1+\mu)} \cdot \text{sgn}(x)$北美/日本电话(μ=255)
    A-law(A 律)分段对数函数欧洲/中国电话(A=87.6)
    量化与视频编码的关系

    量化是视频压缩中控制码率和质量的核心手段

    1. H.264 中的 DCT 系数量化使用可变量化步长(由 QP 控制),本质上是非均匀量化思想的延伸

    2. QP 越大 → 量化步长越大 → 更多系数被量化为零 → 码率越低但失真越大

    3. 量化是视频编码中唯一的有损步骤——运动估计、变换、熵编码都是无损的

    PCM 解码与信号重建

    PCM 编码的逆过程是解码与重建——将数字码流还原为模拟信号。解码过程是编码的逆操作:

    PCM 解码原理:解码、DAC、低通滤波
    图 4:PCM 解码与信号重建的完整流程。
  • 解码:将二进制码流还原为量化电平序列。
  • DAC(数模转换):将离散量化电平转换为阶梯状的模拟信号。
  • 低通滤波(LPF):平滑阶梯信号,滤除高频量化噪声,重建连续模拟信号 $\hat{f}(t)$。重建信号 $\hat{f}(t)$ 与原始信号 $f(t)$ 的差异即为量化误差。
  • Step 1:解码(Decoding)

    将接收到的二进制码流还原为量化电平序列。这是编码步骤的简单逆操作:

    接收码流:  011 100 110 101 010 ...
    解码后:    y3  y4  y6  y5  y2  ...  (量化电平值)
    Step 2:数模转换(DAC, Digital-to-Analog Conversion)

    将离散的量化电平转换为连续的模拟电压信号。DAC 输出的是一个阶梯状信号(零阶保持,Zero-Order Hold):

    $$f_{\text{DAC}}(t) = \hat{f}(nT_s), \quad nT_s \leq t < (n+1)T_s$$

    每个采样值在一个采样周期内保持不变,形成阶梯波形。

    D/A 数模转换原理:权电阻网络与 R-2R 梯形网络
    图 5:D/A 转换原理。上:DAC 的基本组成——数字输入(二进制码字)通过模拟电子开关控制权电阻网络或 R-2R 梯形网络,将数字量转换为模拟电压/电流输出。下左:权电阻网络 DAC——每个比特位控制一个电阻,电阻值按 $2^n$ 比例分配($R, 2R, 4R, 8R$),通过运算放大器求和输出。下右:R-2R 梯形网络 DAC——只使用两种阻值 $R$$2R$,避免了权电阻网络中电阻值范围过大的问题,是实际 DAC 芯片中最常用的架构。
    DAC 的核心原理

    DAC 的本质是将二进制数字量转换为模拟电压/电流。以 $n$-bit DAC 为例:

    $$V_{\text{out}} = V_{\text{ref}} \times \frac{D}{2^n}$$

    其中 $D$ 是输入的数字量(0 到 $2^n - 1$),$V_{\text{ref}}$ 是参考电压。

    两种经典 DAC 架构 权电阻网络(Weighted Resistor DAC)

    每个比特位控制一个电阻开关,电阻值按二进制权重分配:

    • 最高位(MSB):电阻 $R$,权重 $1/2$
    • 次高位:电阻 $2R$,权重 $1/4$
    • 第三位:电阻 $4R$,权重 $1/8$
    • 最低位(LSB):电阻 $2^{n-1}R$,权重 $1/2^n$

    所有支路电流通过运算放大器求和,输出电压与数字量成正比。

    缺点$n$ 位 DAC 需要电阻值范围从 $R$$2^{n-1}R$。对于 12-bit DAC,电阻比为 $2^{11} = 2048:1$,难以保证精度。

    R-2R 梯形网络(R-2R Ladder DAC)

    只使用两种阻值 $R$$2R$,通过递归的梯形结构实现二进制权重分配:

    • 每个节点向左看的等效电阻都是 $2R$
    • 每个节点的电流被精确地一分为二
    • 从 MSB 到 LSB,电流按 $1/2, 1/4, 1/8, \ldots$ 递减

    优点

    1. 只需两种阻值,易于集成制造

    2. 电阻比精度容易保证

    3. 适用于高位深 DAC(12-bit、16-bit 甚至更高)

    R-2R 梯形网络是实际 DAC 芯片(如音频 DAC、视频 DAC)中最常用的架构。

    DAC 的关键性能指标
    指标含义典型值
    分辨率(Resolution)输出电平的最小变化量$V_{\text{ref}} / 2^n$
    建立时间(Settling Time)输出稳定到目标值的时间几 ns 到几 μs
    线性度(Linearity)输出与理想值的最大偏差< 1 LSB
    采样率(Sample Rate)每秒可转换的次数音频:44.1–192 kHz;视频:数十 MHz
    零阶保持(Zero-Order Hold)效应

    DAC 输出的阶梯信号在频域上等效于理想采样信号通过一个 sinc 滤波器:

    $$H_{\text{ZOH}}(f) = \text{sinc}(\pi f T_s) = \frac{\sin(\pi f T_s)}{\pi f T_s}$$

    这意味着 DAC 输出在高频处有sinc 衰减——在奈奎斯特频率 $f_s/2$ 处衰减约 3.9 dB。高质量的重建系统需要补偿这种衰减。

    Step 3:低通滤波(LPF, Low-Pass Filter)

    DAC 输出的阶梯信号包含高频成分(由阶梯跳变引入),需要通过重建低通滤波器(Reconstruction Filter)平滑:

    • 截止频率设为 $f_s / 2$(奈奎斯特频率)
    • 滤除采样引入的高频镜像分量
    • 输出平滑的连续模拟信号 $\hat{f}(t)$
    重建信号的质量

    重建信号 $\hat{f}(t)$ 与原始信号 $f(t)$ 的差异完全来自量化误差:

    $$\hat{f}(t) = f(t) + e_q(t)$$

    采样和编码本身不引入失真(在满足奈奎斯特定理的前提下)。量化是唯一引入不可逆失真的步骤

    编解码完整链路总结
    编码端(ADC):
    模拟信号 f(t) → 采样 → f(nTs) → 量化 → f̂(nTs) → 编码 → 二进制码流
    
    传输/存储
    
    解码端(DAC):
    二进制码流 → 解码 → f̂(nTs) → DAC → 阶梯信号 → LPF → 重建信号 f̂(t)
    PCM 编解码与视频编码的关系

    PCM 的编解码框架是所有数字视频编码的基础原型:

    • 视频编码中的反量化 + 反变换 + 重建帧就是 PCM 解码思想在变换域的推广
    • H.264 解码器中的反量化 → 反 DCT → 重建帧 → 环路滤波对应 PCM 的解码 → DAC → LPF
    • 环路滤波(Deblocking Filter)本质上是一种自适应低通滤波器,用于消除量化引入的块效应
    PCM 码率计算

    PCM 的原始码率(未压缩)为:

    $$R_b = f_s \times n \text{ (bps)}$$

    对于单通道信号。对于视频:

    $$R_b = W \times H \times f_{\text{frame}} \times n_{\text{channels}} \times n_{\text{bits}}$$

    以 1080p、30fps、8-bit RGB(3 通道)为例:

    $$R_b = 1920 \times 1080 \times 30 \times 3 \times 8 \approx 1.49 \text{ Gbps}$$

    这就是为什么视频压缩如此重要——原始的 PCM 码率太高,无法直接传输或存储。

    PCM 的变体
    变体全称原理应用
    DPCMDifferential PCM编码相邻采样值的差值图像/语音压缩
    ADPCMAdaptive DPCM自适应量化步长的 DPCM电话、G.726 音频
    Δ-ModulationDelta Modulation1-bit DPCM,只编码增减简单语音编码

    DPCM 的思想直接影响了视频编码中的帧内预测帧间预测——都是利用相邻样本的相关性,只编码差值(残差)而非原始值。

    三原色原理:RGB 加色模型

    数字视频中所有颜色的基础是三原色光:红(Red)、绿(Green)、蓝(Blue)。这三种颜色被称为加色三原色,因为将它们以不同强度叠加可以产生几乎所有人眼可见的颜色。

    为什么是红、绿、蓝?

    人眼视网膜上有三种视锥细胞(Cone Cells),分别对红、绿、蓝三种波长的光最敏感。大脑通过这三种细胞的信号组合来感知颜色。RGB 模型正是基于这一生理事实——只要精确控制红、绿、蓝三种光的强度,就能"欺骗"人眼看到任何颜色。

    加色混合规律
    混合结果说明
    R + G黄色(Yellow)红绿叠加
    G + B青色(Cyan)绿蓝叠加
    B + R品红(Magenta)蓝红叠加
    R + G + B白色(White)三原色等量叠加
    无光黑色(Black)零强度
    RGB 三原色加色混合与 Bayer 滤色阵列
    图 6:RGB 三原色加色混合示意——红、绿、蓝三色光叠加产生黄、青、品红及白色。右侧为 Bayer 滤色阵列的 GR/BG 排列模式,绿色像素占 50%。
    RGB 在数字视频中的表示

    在 8-bit RGB 系统中,每个颜色通道用 0–255 的整数表示:

    • (0, 0, 0) = 黑色
    • (255, 255, 255) = 白色
    • (255, 0, 0) = 纯红
    • (0, 255, 0) = 纯绿
    • (0, 0, 255) = 纯蓝
    • (255, 255, 0) = 黄色

    每个像素需要 24 bit(3 × 8 bit)来存储完整的 RGB 信息。这就是为什么未压缩视频的数据量如此巨大。

    加色 vs 减色
    模型三原色混合原理应用场景
    加色模型(RGB)红、绿、蓝光的叠加,越加越亮显示器、投影仪、摄像机
    减色模型(CMYK)青、品红、黄颜料的吸收,越加越暗印刷、绘画

    视频编码使用的是加色模型(RGB),因为视频是在发光设备上显示的。

    摄像机感光元件:CCD 与 CMOS

    数字视频的每一帧都来自摄像机的感光元件。感光元件将入射光转换为电信号,再经过模数转换(ADC)变为数字像素值。

    两种主流感光元件
    特性CCD(Charge-Coupled Device)CMOS(Complementary MOS)
    工作原理电荷逐行转移至统一 ADC每个像素自带 ADC
    读出方式全局快门(Global Shutter)滚动快门(Rolling Shutter)为主
    功耗低(约 CCD 的 1/10)
    成本高(专用制造工艺)低(标准 CMOS 工艺)
    噪声低(统一 ADC)较高(像素级 ADC 不一致)
    速度较慢快(并行读出)
    应用天文、医疗、工业检测手机、相机、监控、绝大多数消费级设备
    CMOS 已成为绝对主流。现代手机、数码相机、安防摄像头几乎全部使用 CMOS 传感器。CMOS 的优势在于:

    1. 低成本:使用标准半导体工艺,与 CPU/内存同线生产

    2. 低功耗:适合移动设备

    3. 高速度:并行读出支持高帧率(120fps、240fps 甚至更高)

    4. 集成度高:可以在同一芯片上集成图像处理电路

    Bayer 滤色阵列(CFA)

    CMOS 感光元件本身只能感知光的强度(亮度),不能感知颜色。每个光电二极管输出的是一个灰度值。

    为了让 CMOS "看到"颜色,在每个像素上方覆盖一个微型滤色片,只允许特定颜色的光通过。最经典的排列方式是 Bayer 滤色阵列(Bayer Color Filter Array, CFA),由 Kodak 的 Bryce Bayer 于 1976 年发明。

    Bayer 排列模式

    Bayer CFA 使用 2×2 的基本单元重复排列:

    G  R
    B  G
    • 绿色(G)占 50%(2/4 个像素)
    • 红色(R)占 25%(1/4 个像素)
    • 蓝色(B)占 25%(1/4 个像素)
    Bayer 滤色阵列排列模式
    图 7:Bayer 滤色阵列(CFA)的完整排列模式。奇数行为 G-R-G-R-G-R 交替,偶数行为 B-G-B-G-B-G 交替。绿色像素占 50%,红色和蓝色各占 25%,模拟人眼对绿色亮度更敏感的生理特性。
    为什么绿色占 50%?

    这与人眼的视觉特性直接相关:

    1. 人眼对绿色波段的亮度最敏感(视锥细胞中 M-cone 对 ~530nm 绿光响应最强)

    2. 亮度信息(Luma)主要来自绿色通道

    3. 更多的绿色采样 = 更准确的亮度信息 = 更好的视觉质量

    这也解释了为什么 YUV 色彩空间中 Y(亮度)的权重公式里绿色的系数最大:

    $$Y = 0.299R + 0.587G + 0.114B$$

    绿色权重 0.587 远大于红色 0.299 和蓝色 0.114。

    去马赛克(Demosaicing)

    Bayer CFA 的每个像素只记录了一种颜色分量(R、G 或 B),要得到完整的 RGB 像素,需要通过去马赛克算法从相邻像素插值出缺失的颜色分量:

    原始 Bayer 数据:      去马赛克后:
    G  R  G  R          (R,G,B) (R,G,B) (R,G,B) (R,G,B)
    B  G  B  G    →     (R,G,B) (R,G,B) (R,G,B) (R,G,B)
    G  R  G  R          (R,G,B) (R,G,B) (R,G,B) (R,G,B)
    B  G  B  G          (R,G,B) (R,G,B) (R,G,B) (R,G,B)

    去马赛克是摄像机 ISP(Image Signal Processor)的核心步骤之一。简单的算法使用双线性插值,高级算法使用边缘自适应插值以减少伪彩色和锯齿。

    Bayer CFA 与视频编码的关系

    Bayer CFA 直接影响了视频编码的设计决策:

    1. 4:2:0 色度子采样的合理性:Bayer 本身就已经对色度做了稀疏采样(R 和 B 各只占 25%),进一步做 4:2:0 子采样不会造成明显的视觉损失

    2. YUV 优于 RGB:从 Bayer 数据转换到 YUV 比转换到 RGB 更自然,因为亮度信息(主要来自 G)已经是最密集的采样

    3. 去马赛克质量影响编码效率:去马赛克引入的伪影(伪彩色、锯齿)会增加高频噪声,降低编码效率

    白平衡校正(White Balance)

    白平衡是 ISP 流水线中去马赛克之后、色彩校正之前的关键步骤。它的目标是消除光源色偏,使白色物体在任何光照条件下都呈现白色。

    为什么需要白平衡?

    不同光源的色温(Color Temperature)不同,导致同一物体在不同光源下呈现不同的颜色:

    光源色温(K)色偏倾向示例
    烛光~1800K严重偏红/黄烛光晚餐
    白炽灯~2800K偏红/黄室内照明
    荧光灯~4000K偏绿办公室照明
    日光(正午)~5500K中性(标准白)室外晴天
    阴天~6500K偏蓝多云天气
    蓝天阴影~8000K+严重偏蓝阴影区域

    人眼具有色彩恒常性(Color Constancy)——大脑自动补偿光源色偏,使白色物体在任何光线下看起来都是白色。但摄像机传感器没有这种能力,必须通过白平衡算法来模拟。

    白平衡的原理

    白平衡的核心思想很简单:调整 R、G、B 三个通道的增益,使场景中的"白色"或"中性灰色"在三个通道上具有相等的响应

    $$R_{\text{wb}} = R_{\text{raw}} \times G_R$$
    $$G_{\text{wb}} = G_{\text{raw}} \times G_G$$
    $$B_{\text{wb}} = B_{\text{raw}} \times G_B$$

    其中 $G_R, G_G, G_B$ 是三个通道的增益系数。通常将 G 通道增益设为 1($G_G = 1$),只调整 R 和 B 通道。

    白平衡增益的确定
    方法原理优点缺点应用
    灰度世界法(Gray World)假设整幅图像的平均颜色为中性灰简单、快速大面积单色场景失效自动白平衡基础算法
    完美反射法(White Patch)假设图像中最亮的点是白色对高对比度场景有效高光过曝时失效自动白平衡
    色温估计法从图像统计中估计光源色温较准确计算复杂高级 AWB
    手动预设用户选择光源类型(日光/白炽灯/荧光灯)可靠需要用户干预专业摄影
    灰度世界法详解

    灰度世界假设(Gray World Assumption)是最经典的自动白平衡算法:

    1. 计算整幅图像 R、G、B 通道的平均值:$\bar{R}, \bar{G}, \bar{B}$

    2. 计算平均灰度:$\bar{K} = (\bar{R} + \bar{G} + \bar{B}) / 3$

    3. 计算各通道增益:$G_R = \bar{K}/\bar{R}, \quad G_G = \bar{K}/\bar{G}, \quad G_B = \bar{K}/\bar{B}$

    4. 应用增益:$R' = R \times G_R, \quad G' = G \times G_G, \quad B' = B \times G_B$

    白平衡在 ISP 流水线中的位置

    完整的摄像机 ISP 流水线:

    镜头 → CMOS 传感器(Bayer CFA)→ ADC
        → 黑电平校正(Black Level Correction)
        → 镜头阴影校正(Lens Shading Correction)
        → 去马赛克(Demosaicing)→ 得到 RGB
        → 白平衡(White Balance)← 消除光源色偏
        → 色彩校正(Color Correction)← 校正传感器光谱响应
        → 伽马校正(Gamma Correction)← 非线性编码
        → YUV 转换 → 视频编码器(H.264 等)

    白平衡和色彩校正的区别:

    步骤解决的问题方法本质
    白平衡光源色偏3 通道独立增益"这个光是什么颜色"
    色彩校正传感器光谱响应偏差3×3 矩阵变换"这个传感器看到的是什么颜色"

    白平衡是对角矩阵(3 个独立增益),色彩校正是满矩阵(9 个系数,含通道间串扰补偿)。两者配合才能得到准确的颜色再现。

    色彩校正(Color Correction)

    去马赛克后得到的 RGB 数据还不能直接使用,因为 Bayer 滤色片的光谱响应与理想的人眼三刺激函数(CIE Color Matching Functions)并不一致。此外,不同光源(日光、白炽灯、荧光灯)的光谱分布不同,会导致同一物体在不同光照下呈现不同的颜色。

    色彩校正的目的

    色彩校正将传感器捕获的"原始 RGB"转换为"标准 RGB"(如 sRGB 或 BT.709),使颜色在不同设备和不同光照条件下保持一致。

    色彩校正原理:3×3 色彩校正矩阵
    图 8:色彩校正原理。左:摄像机传感器的 RGB 光谱响应曲线与 CIE 标准观察者曲线的差异——传感器滤色片的红、绿、蓝响应与人眼视锥细胞的响应不完全匹配。右:3×3 色彩校正矩阵(CCM)——通过线性变换将传感器原始 RGB 值 $[R_s, G_s, B_s]^T$ 映射到标准 RGB 值 $[R_c, G_c, B_c]^T$。矩阵的非对角元素表示通道间的串扰补偿。
    3×3 色彩校正矩阵(CCM)

    最常用的色彩校正方法是 3×3 线性矩阵变换

    $$\begin{bmatrix} R_c \\ G_c \\ B_c \end{bmatrix} = \begin{bmatrix} a_{11} & a_{12} & a_{13} \\ a_{21} & a_{22} & a_{23} \\ a_{31} & a_{32} & a_{33} \end{bmatrix} \begin{bmatrix} R_s \\ G_s \\ B_s \end{bmatrix}$$

    其中:

    • $[R_s, G_s, B_s]^T$ 是传感器原始 RGB 值
    • $[R_c, G_c, B_c]^T$ 是校正后的标准 RGB 值
    • $3 \times 3$ 矩阵的 9 个系数通过标定过程确定
    矩阵系数的标定方法

    1. 使用标准色卡(如 Macbeth ColorChecker,24 色)

    2. 在标准光源下拍摄色卡,获取传感器的 RGB 响应

    3. 已知色卡每个色块的标准 RGB/XYZ 值

    4. 通过最小二乘法求解最优的 3×3 矩阵

    色彩校正与白平衡的关系

    白平衡(White Balance)和色彩校正(Color Correction)是 ISP 流水线中两个不同但相关的步骤:

    步骤目的方法位置
    白平衡消除光源色偏,使白色物体在任何光源下都呈现白色调整 R/G/B 通道增益去马赛克之前或之后
    色彩校正校正传感器光谱响应与人眼的差异3×3 矩阵变换白平衡之后

    白平衡解决的是"光源颜色"问题,色彩校正解决的是"传感器颜色"问题。

    伽马校正(Gamma Correction)

    伽马校正是数字视频中最重要也最容易被忽略的非线性处理步骤。它解决了人眼感知的非线性显示设备的非线性之间的匹配问题。

    伽马校正原理:CRT 非线性与人眼感知的匹配
    图 9:伽马校正原理。左上:人眼对亮度的感知是非线性的——在暗区对亮度变化更敏感,在亮区较不敏感。右上:CRT 显示器的电压-亮度响应曲线近似 $L = V^{2.2}$ 的幂函数关系。下方:伽马校正的完整流程——在编码端对线性光信号施加 $\gamma = 1/2.2 \approx 0.45$ 的预校正(编码伽马),在显示端 CRT 自然施加 $\gamma = 2.2$ 的显示伽马,两者抵消后实现端到端的线性再现。伽马校正同时提高了暗部的量化精度,使有限的比特位更有效地分配给人眼敏感的区域。
    为什么需要伽马校正?

    有两个独立的原因,恰好互相配合:

    原因 1:CRT 显示器的非线性

    CRT(阴极射线管)显示器的电子枪输出电压与屏幕亮度之间的关系近似幂函数:

    $$L = V^{\gamma_{\text{display}}} \approx V^{2.2}$$

    这意味着:输入电压 0.5(50%),输出亮度只有 $0.5^{2.2} \approx 0.22$(22%)。如果不做补偿,图像会严重偏暗。

    原因 2:人眼感知的非线性

    人眼对亮度的感知近似对数关系——在暗区对亮度变化非常敏感,在亮区较不敏感。这恰好与 CRT 的非线性方向相反。

    伽马校正的原理

    在编码端(摄像机/图像处理),对线性光信号施加预校正(编码伽马):

    $$V_{\text{encoded}} = V_{\text{linear}}^{1/\gamma} \approx V_{\text{linear}}^{0.45}$$
    伽马校正端到端流程示意图
    图 10:伽马校正端到端流程示意。
  • 光电转换:摄像机传感器将入射光强度转换为电信号(线性响应)。
  • 伽马预失真:对电信号施加 $\gamma = 0.45$ 的幂函数变换(编码伽马),拉伸暗部、压缩亮部。
  • 传输:编码后的信号通过存储或信道传输。
  • 显示伽马:CRT/LCD 显示器施加 $\gamma = 2.2$ 的幂函数响应。
  • 电光转换:最终输出的亮度与原始入射光成线性关系。整个系统的端到端伽马值 $\gamma_{\text{system}} = 0.45 \times 2.2 \approx 1.0$,实现线性再现。
  • 在显示端,CRT 自然施加显示伽马:

    $$L_{\text{display}} = V_{\text{encoded}}^{\gamma} = (V_{\text{linear}}^{1/\gamma})^{\gamma} = V_{\text{linear}}$$

    两者抵消,实现端到端的线性亮度再现。

    伽马校正的额外好处:优化量化精度

    伽马校正不仅补偿了 CRT 的非线性,还优化了量化比特的分配

    • 编码伽马 $\gamma < 1$ 的幂函数拉伸了暗部压缩了亮部
    • 在 8-bit 量化下,暗部获得了更多的量化级数
    • 这与人眼的感知特性完美匹配——暗部更敏感,需要更精细的量化
    线性亮度伽马编码后(γ=0.45)8-bit 量化值
    0.010.12632
    0.100.35590
    0.500.732187
    1.001.000255

    可以看到,线性亮度 0.01(1%)在线性量化下只对应值 2.55(几乎无法区分),但伽马编码后对应值 32——暗部细节被有效保留。

    标准伽马曲线
    标准伽马值说明
    sRGB~2.2(分段函数)线性段(<0.0031308)+ 幂函数段(γ≈2.4)
    BT.709(HDTV)~1/0.45(分段函数)线性段 + 幂函数段
    BT.2020(UHDTV)同 BT.709用于 HDR 时改用 PQ/HLG
    DCI-P3(电影)2.6影院投影标准

    sRGB 和 BT.709 使用分段函数而非纯幂函数,是为了避免在零附近的数值问题($x^{0.45}$$x \to 0$ 时导数趋于无穷)。

    伽马校正与视频编码的关系

    伽马校正对视频编码有重要影响:

    1. 所有标准视频信号都是伽马编码后的信号——H.264 编码的像素值已经是伽马校正后的非线性值

    2. 量化效率提升:伽马编码使 8-bit 量化在感知上等效于约 12-bit 线性量化

    3. 色度子采样的合理性:伽马编码后的信号中,亮度信息已经承载了大部分感知信息,色度可以安全地做 4:2:0 子采样

    4. HDR 视频:HDR 使用 PQ(Perceptual Quantizer, SMPTE ST 2084)或 HLG(Hybrid Log-Gamma)替代传统伽马曲线,以支持更大的亮度范围(0–10000 nits)

    逐行扫描 vs 隔行扫描
    扫描方式原理标记示例
    逐行扫描(Progressive)每帧扫描所有行p1080p、720p
    隔行扫描(Interlaced)每场扫描一半行,两场组成一帧i1080i、576i

    隔行扫描是 CRT 电视时代的遗留技术,用于在有限带宽下减少闪烁感。现代数字视频基本使用逐行扫描。H.264 支持隔行扫描(通过 MBAFF/PAFF 编码工具),但实际应用中逐行扫描占绝大多数。

    像素(Pixel)
    像素是数字图像的最小组成单元。每个像素记录了图像在某个空间位置上的光强和颜色信息。

    在灰度图像中,每个像素只有一个亮度分量(Luminance),通常用 8-bit 表示(0–255,0 为纯黑,255 为纯白)。

    在彩色图像中,每个像素由多个分量组成:

    • RGB 色彩空间:红(R)、绿(G)、蓝(B)三个分量
    • YUV 色彩空间:亮度(Y)、蓝色色度(U/Cb)、红色色度(V/Cr)三个分量

    像素在空间上排列成二维网格,水平方向的像素数 × 垂直方向的像素数就是图像的分辨率

    分辨率(Resolution)

    分辨率定义了图像在水平和垂直方向上的像素数量,记作 $W \times H$。分辨率越高,图像包含的细节越丰富,但数据量也越大。

    标准分辨率体系

    在视频编码和安防监控领域,有一套从早期视频会议发展而来的标准分辨率体系:

    名称分辨率像素数与 CIF 的关系典型应用
    QCIF176×14425,3441/4 CIF早期移动视频
    CIF352×288101,376基准H.261/H.263 视频会议
    2CIF / Half D1704×288202,7522× CIF(水平翻倍)安防监控(宽屏)
    4CIF704×576405,5044× CIF安防监控、标清编码
    D1720×576(PAL)/ 720×480(NTSC)~414,720≈4× CIFDVD、标清电视
    16CIF1408×11521,622,01616× CIF高清过渡格式
    CIF 的由来

    CIF(Common Intermediate Format,通用中间格式)是 H.261 标准定义的分辨率(352×288)。它的设计考虑了 PAL 和 NTSC 两种电视制式的兼容性:

    • 水平 352 像素:PAL 和 NTSC 的折中
    • 垂直 288 行:PAL 制式 576 行的一半(隔行扫描的一场)
    现代分辨率体系
    名称分辨率像素数典型应用
    SD(标清)720×576(PAL)/ 720×480(NTSC)~414KDVD、模拟电视数字化
    HD(720p)1280×720~922K早期高清视频
    Full HD(1080p)1920×1080~2.07M主流视频、蓝光
    2K2560×1440~3.69M显示器、手机屏幕
    4K UHD3840×2160~8.29M超高清电视、流媒体
    8K UHD7680×4320~33.18M下一代超高清

    从 CIF 到 4K UHD,像素数增长了约 80 倍,这对视频编码的压缩效率提出了巨大挑战。

    帧率(Frame Rate)
    帧率(Frame Rate)定义为每秒显示的图像帧数,单位是 fps(frames per second)。帧率决定了视频的时间分辨率——帧率越高,运动越流畅,但数据量也越大。 常见帧率及其来源
    帧率来源 / 标准典型应用
    15 fps早期视频会议低码率通信
    23.976 fps电影胶片(24 fps 的 NTSC 兼容版)电影、影视制作
    24 fps电影胶片标准电影放映
    25 fpsPAL 制式(50 Hz 电网 / 2)欧洲/中国电视
    29.97 fpsNTSC 制式(60 Hz 电网 / 2 的彩色兼容版)北美/日本电视
    30 fpsNTSC 制式(近似值)网络视频、手机录制
    50 fpsPAL 高帧率体育直播(欧洲)
    59.94 / 60 fpsNTSC 高帧率体育直播、游戏
    120 fps超高帧率慢动作回放、VR
    帧率与数据量的关系

    未压缩视频的原始数据量与帧率成正比:

    $$\text{原始码率} = W \times H \times \text{每像素比特数} \times \text{帧率}$$

    以 1080p、8-bit RGB 为例:

    帧率原始码率
    24 fps~1.19 Gbps
    30 fps~1.49 Gbps
    60 fps~2.99 Gbps

    帧率翻倍意味着数据量翻倍。这就是为什么高帧率视频对编码器提出了更高要求。

    码率(Bitrate)
    码率(Bitrate)是编码后每秒视频数据所占的比特数,单位通常是 kbps(千比特/秒)或 Mbps(兆比特/秒)。码率是视频压缩中最核心的工程参数——它直接决定了视频的文件大小和传输带宽需求。 码率的三种控制模式
    模式全称原理优势劣势
    CBRConstant Bitrate码率恒定,每秒分配相同比特带宽可控,适合实时传输复杂场景质量下降,简单场景浪费比特
    VBRVariable Bitrate码率可变,复杂场景多分配比特质量稳定,压缩效率高峰值码率不可控,不适合实时传输
    ABRAverage Bitrate码率在目标值附近波动兼顾质量和带宽需要两遍编码(2-pass)
    典型码率参考

    以下是 H.264 编码下不同分辨率和质量的典型码率:

    分辨率帧率低质量中等质量高质量
    CIF (352×288)30fps128 kbps384 kbps768 kbps
    SD (720×576)25fps500 kbps1.5 Mbps3 Mbps
    720p30fps1 Mbps2.5 Mbps5 Mbps
    1080p30fps2 Mbps5 Mbps10 Mbps
    1080p60fps3 Mbps8 Mbps15 Mbps
    4K30fps8 Mbps20 Mbps40 Mbps
    码率与分辨率、帧率的关系

    码率需求大致与像素数和帧率的乘积成正比,但并非严格的线性关系:

    • 分辨率翻倍(如 720p → 1080p),码率需求约增加 2–3 倍
    • 帧率翻倍(如 30fps → 60fps),码率需求约增加 1.5–2 倍(因为帧间相关性增强,帧间预测效率提高)
    码率计算公式
    $$\text{文件大小(字节)} = \frac{\text{码率(bps)} \times \text{时长(秒)}}{8}$$

    例如,一段 10 分钟的 1080p 视频(5 Mbps 码率):

    $$\text{文件大小} = \frac{5 \times 10^6 \times 600}{8} = 375 \text{ MB}$$
    逐行扫描 vs 隔行扫描
    扫描方式原理标记示例
    逐行扫描(Progressive)每帧扫描所有行p1080p、720p
    隔行扫描(Interlaced)每场扫描一半行,两场组成一帧i1080i、576i

    隔行扫描是 CRT 电视时代的遗留技术,用于在有限带宽下减少闪烁感。现代数字视频基本使用逐行扫描。H.264 支持隔行扫描(通过 MBAFF/PAFF 编码工具),但实际应用中逐行扫描占绝大多数。

    专题三
    数据冗余和压缩
    视频中的四种冗余

    视频压缩的本质是消除冗余。视频数据中存在四种主要冗余,其中空间冗余时间冗余是最核心的两种。

    空间冗余(Spatial Redundancy)
    定义

    空间冗余是指同一帧内相邻像素之间的强相关性。在自然图像中,相邻像素的值通常非常接近——一片蓝天、一面白墙、一个人的皮肤,这些区域内的像素值变化缓慢甚至几乎不变。

    数学描述

    对于一幅图像 $f(x, y)$,相邻像素之间的相关性可以用自相关函数衡量:

    $$R(\Delta x, \Delta y) = \frac{E[f(x,y) \cdot f(x+\Delta x, y+\Delta y)]}{E[f^2(x,y)]}$$

    对于自然图像,当 $(\Delta x, \Delta y)$ 很小时,$R \approx 1$(高度相关);随着距离增大,相关性逐渐衰减。典型的一阶马尔可夫模型:

    $$R(\Delta x) \approx \rho^{\Delta x}, \quad \rho \in [0.9, 0.99]$$

    这意味着相邻像素之间的相关系数高达 0.9–0.99——绝大部分信息是重复的。

    直观示例

    考虑一个 4×4 的像素块(灰度值):

    120  122  121  119
    121  123  122  120
    119  121  120  118
    118  120  119  117

    这 16 个像素的值都在 117–123 之间,变化极小。如果直接存储,需要 $16 \times 8 = 128$ bit。但如果存储差值(DPCM):

    120   +2   -1   -2
     +1   +2   -1   -2
     -2   +2   -1   -2
     -1   +2   -1   -2

    差值范围只有 -2 到 +2,用 3-bit 即可编码(而非 8-bit),总比特数降为 $16 \times 3 = 48$ bit(节省 62.5%)。

    消除空间冗余的技术
    技术原理应用
    帧内预测用相邻已编码像素预测当前像素H.264 4×4 / 16×16 帧内预测
    变换编码(DCT)将空间域信号变换到频率域,能量集中在低频JPEG、H.264 整数 DCT
    量化丢弃高频系数(人眼不敏感的细节)所有有损压缩
    差分编码(DPCM)编码相邻像素的差值而非原始值JPEG DC 系数编码
    变换编码为什么能消除空间冗余?

    DCT 的核心作用是将高度相关的空间域像素变换为几乎不相关的频率域系数

    • 空间域:相邻像素高度相关 → 冗余大
    • 频率域:DCT 系数之间几乎不相关 → 冗余小
    • 能量集中:大部分能量集中在少数低频系数(DC 和前几个 AC)→ 高频系数可以大胆量化为零

    这就是为什么 DCT 被称为"去相关变换"(Decorrelating Transform)。

    时间冗余(Temporal Redundancy)
    定义

    时间冗余是指相邻帧之间像素的强相关性。在视频中,相邻帧通常拍摄的是同一场景,只有少量物体在运动,大部分背景几乎不变。这是视频压缩中贡献最大的冗余来源(约占总压缩效率的 50%)。

    数学描述

    对于视频序列 $f(x, y, t)$,相邻帧之间的相关性:

    $$R_t(\Delta t) = \frac{E[f(x,y,t) \cdot f(x,y,t+\Delta t)]}{E[f^2(x,y,t)]}$$

    对于典型的 30fps 视频,相邻帧($\Delta t = 1/30$ 秒)之间的相关系数通常在 0.95–0.99 之间——比空间相关性更高。

    直观示例

    考虑一个固定镜头拍摄的场景:

    帧 t:   [背景: 蓝天 + 建筑] [运动物体: 行人从左向右走]
    帧 t+1: [背景: 蓝天 + 建筑] [运动物体: 行人向右移动了 5 像素]
    帧 t+2: [背景: 蓝天 + 建筑] [运动物体: 行人向右移动了 10 像素]

    背景部分(约占画面的 80%)在三帧中完全相同。如果每帧独立编码,背景信息被重复编码了 3 次。利用时间冗余,只需:

    1. 在帧 t 中完整编码背景(I 帧)

    2. 在帧 t+1 和 t+2 中,只编码行人的运动(运动矢量 + 残差)

    3. 背景部分直接"复制"帧 t 的数据

    时间冗余 vs 空间冗余的对比
    维度空间冗余时间冗余
    相关性来源同一帧内相邻像素相邻帧之间对应像素
    相关系数0.90–0.990.95–0.99(通常更高)
    消除方法帧内预测 + DCT帧间预测 + 运动估计
    压缩贡献~30%~50%(最大贡献)
    典型技术4×4/16×16 帧内模式P 帧 / B 帧 + MV
    失效场景高频纹理区域(草地、毛发)场景切换、快速运动
    消除时间冗余的技术
    技术原理效果
    帧间预测用参考帧的像素预测当前帧消除静态背景冗余
    运动估计(ME)在参考帧中搜索最佳匹配块补偿物体运动
    运动补偿(MC)用运动矢量指向的参考块做预测精确对齐运动区域
    多参考帧从多个历史帧中选择最佳匹配处理遮挡和周期运动
    B 帧双向预测同时参考前后帧进一步降低残差
    时间冗余的局限性

    时间冗余在以下场景中会显著降低:

    1. 场景切换(Scene Cut):前后帧是完全不同的场景,相关性接近零

    2. 快速运动:物体运动超出搜索范围,运动估计失效

    3. 遮挡/显露:物体被遮挡或新物体出现,参考帧中没有对应信息

    4. 光照变化:闪光灯、淡入淡出等全局亮度变化

    这些情况下,编码器会自动回退到帧内编码(I 帧或帧内宏块)。

    视觉冗余(Visual Redundancy)
    定义

    视觉冗余是指人眼视觉系统(HVS)对某些信息不敏感,这些信息可以被丢弃而不影响主观感知质量。这是有损压缩的理论基础。

    人眼的视觉特性决定了哪些信息可以安全丢弃:

    视觉特性含义压缩利用方式
    亮度敏感 > 色度敏感人眼对亮度变化的敏感度远高于色度4:2:0 色度子采样(色度数据减半)
    低频敏感 > 高频敏感人眼对低频(大面积渐变)更敏感,对高频(细节纹理)较不敏感DCT 高频系数量化更激进
    对比度掩蔽在纹理复杂区域,人眼对失真更不敏感自适应量化(纹理区域用更大 QP)
    运动掩蔽快速运动区域人眼分辨力下降运动区域可降低编码精度
    色度子采样:最经典的视觉冗余利用

    YUV 4:2:0 格式将色度分辨率降为亮度的 1/4(水平 × 垂直各减半),数据量减少 50%,但人眼几乎无法察觉差异。

    量化:视觉冗余的核心工具

    量化步长的选择直接利用了视觉冗余:

    • 低频系数:小量化步长(保留细节)
    • 高频系数:大量化步长(大胆丢弃)
    • 色度系数:比亮度更激进的量化
    统计冗余(Statistical Redundancy)
    定义

    统计冗余是指编码后的符号在概率分布上不均匀——某些符号出现频率高,某些出现频率低。熵编码利用这种不均匀性,给高频符号分配短码字,给低频符号分配长码字。

    典型示例

    DCT 量化后的系数分布极度不均匀:

    • 零值系数占 70–90%(高频被量化为零)
    • ±1 占非零系数的大部分
    • 大值系数极少出现
    符号出现概率定长编码Huffman 编码节省
    080%3 bits1 bit67%
    ±112%3 bits3 bits0%
    ±25%3 bits4 bits-33%
    其他3%3 bits5–8 bits

    虽然个别符号的码长增加了,但平均码长从 3 bits 降到了约 1.5 bits(节省 50%)。

    消除统计冗余的技术
    技术原理应用
    Huffman 编码根据符号频率构建最优前缀码JPEG、MPEG-1/2
    算术编码将整个符号序列映射为 [0,1) 区间的一个实数H.264 CABAC、HEVC
    指数哥伦布码对小值高效的变长码H.264 运动矢量、宏块类型
    CAVLC上下文自适应 VLCH.264 Baseline Profile
    CABAC上下文自适应二进制算术编码H.264 Main/High Profile
    压缩比的概念

    以一个 1080p、30fps、8-bit 的未压缩视频为例:

    $$\text{原始码率} = 1920 \times 1080 \times 3 \text{(RGB 三通道)} \times 8 \text{ bit} \times 30 \text{ fps} \approx 1.49 \text{ Gbps}$$

    经过 H.264 压缩后,典型码率为 5–20 Mbps,压缩比达到 75–300 倍

    这种巨大的压缩比不是单一技术实现的,而是多种冗余消除技术的组合效果:

    冗余类型消除技术贡献比例(粗略估计)
    空间冗余变换 + 量化~30%
    时间冗余运动估计 + 帧间预测~50%
    视觉冗余色度子采样 + 量化~10%
    统计冗余熵编码~10%
    有损 vs 无损
    压缩类型特点压缩比典型应用
    无损压缩完全可逆,不丢失任何信息2–3 倍医学影像、专业制作
    有损压缩不可逆,丢弃人眼不敏感的信息50–300 倍流媒体、广播、存储

    H.264 是有损压缩标准。量化步骤是不可逆的——被丢弃的高频信息无法恢复。这是高压缩比的代价。

    专题四
    从 RGB 到 YUV 编码
    为什么需要 YUV?

    RGB 色彩空间对人眼的感知特性不够友好:三个通道(R、G、B)都包含亮度和色度信息,无法独立控制。

    YUV 色彩空间将亮度(Y)和色度(U、V)分离:

    • Y(Luma):亮度分量,代表图像的明暗信息
    • U(Cb):蓝色色度分量(B - Y)
    • V(Cr):红色色度分量(R - Y)

    这种分离有两个关键优势:

    1. 人眼对亮度更敏感,对色度较不敏感——可以对色度使用更低的采样率(色度子采样)而不影响视觉质量

    2. 黑白电视兼容——只传输 Y 分量即可显示黑白图像

    RGB 到 YUV 的转换公式

    BT.601 标准(标清视频)的转换公式:

    $$Y = 0.299R + 0.587G + 0.114B$$
    $$U = C_b = 0.564(B - Y)$$
    $$V = C_r = 0.713(R - Y)$$

    BT.709 标准(高清视频)的转换公式:

    $$Y = 0.2126R + 0.7152G + 0.0722B$$

    注意绿色的权重最大(约 0.587 / 0.7152),因为人眼对绿色最敏感。

    视频编码完整流程:RGB 到 YUV 转换、预测、变换、量化、熵编码
    图 11:视频编码完整流水线。输入视频首先从 RGB 转换为 YUV 色彩空间(分离亮度和色度),然后进入编码核心:帧内/帧间预测 → DCT 变换 → 量化 → 熵编码 → 输出码流。重建路径(反量化 → 反 DCT → 环路滤波)生成参考帧供后续帧预测使用。RGB→YUV 转换是整个编码流水线的第一步,也是色度子采样的前提。
    色度子采样(Chroma Subsampling)

    色度子采样是视频压缩中最简单也最有效的技术之一。它利用人眼对色度不敏感的特性,用比亮度更低的分辨率存储色度信息。

    采样格式含义数据量应用
    4:4:4色度与亮度同分辨率100%专业影视制作
    4:2:2水平色度减半67%广播级视频
    4:2:0水平+垂直色度各减半50%消费级视频(H.264 默认)
    4:1:1水平色度 1/450%DV 格式
    色度子采样模式对比:4:4:4、4:2:2、4:2:0 的 Y/Cb/Cr 采样网格
    图 12:色度子采样模式对比。上:4:4:4——Y、Cb、Cr 全分辨率采样,每个像素都有独立的亮度和色度值,数据量 100%。中:4:2:2——Y 全分辨率,Cb/Cr 水平方向每 2 个像素共享 1 个采样(水平减半),数据量 67%。下:4:2:0——Y 全分辨率,Cb/Cr 在水平和垂直方向都每 2 个像素共享 1 个采样(4 个 Y 像素共享 1 组 Cb/Cr),数据量 50%。黄色圆点表示实际采样位置,灰色圆点表示复用相邻采样值。H.264 默认使用 4:2:0 格式。

    4:2:0 是最常用的格式:色度在水平和垂直方向都减半,数据量减少 50%,但视觉质量几乎不受影响。

    YUV 在 H.264 中的处理

    H.264 默认处理 4:2:0 格式的 YUV 数据。对于一个 16×16 的宏块:

    • 亮度(Y):16×16 = 256 个采样点
    • 色度(Cb/Cr):各 8×8 = 64 个采样点

    亮度分量是编码的主要对象,色度分量的编码相对简单(使用较少的预测模式)。

    YUV 的内存布局:Packed vs Planar

    YUV 数据在内存中有两种存储方式:Packed(交错存储)Planar(平面存储)。这两种方式不影响编码算法,但影响数据访问效率和硬件实现。

    YUV 内存布局:Packed 交错存储 vs Planar 平面存储
    图 13:YUV 内存布局对比。上:Packed 格式(YUYV)——Y、U、V 分量交错存储在同一内存区域,每两个像素共享一组 U/V 值(Y0 U0 Y1 V0, Y2 U2 Y3 V2...)。下:Planar 格式——Y、U、V 分量分别存储在三个独立的内存平面中,先存储全部 Y 值,再存储全部 U 值,最后存储全部 V 值。H.264 编码器通常使用 Planar 格式,因为可以独立处理每个分量。
    Packed 格式(交错存储)

    Y、U、V 分量交错存储在同一个内存区域中。常见的排列方式:

    格式排列顺序说明
    YUYV (YUY2)Y0 U0 Y1 V0, Y2 U2 Y3 V2, ...最常用,DirectShow 默认
    UYVYU0 Y0 V0 Y1, U2 Y2 V2 Y3, ...某些采集卡使用
    YVYUY0 V0 Y1 U0, Y2 V2 Y3 U2, ...较少见
    YUV422 Packed 格式内存布局详解
    图 14:YUV422 Packed 格式内存布局详解。以 8 像素的一行为例,YUYV 格式的内存排列为 Y0 U0 Y1 V0, Y2 U2 Y3 V2, Y4 U4 Y5 V4, Y6 U6 Y7 V6。每两个水平相邻的像素共享一组 U/V 值(如像素 0 和像素 1 共享 U0/V0),因此色度水平分辨率减半。每个像素占 2 字节(16-bit),8 像素共 16 字节。这种格式常见于 USB 摄像头输出(UVC 协议默认)和 DirectShow 视频采集。

    Packed 格式的优势是内存连续,适合直接显示(显卡可以直接读取)。但编码时需要先分离 Y、U、V 分量,增加了预处理开销。

    Planar 格式(平面存储)

    Y、U、V 分量分别存储在三个独立的内存区域(平面)中:

    内存布局(4:2:0 Planar):
    
    [Y 平面] Y0 Y1 Y2 Y3 Y4 Y5 Y6 Y7 ... (W×H 字节)
    [U 平面] U0 U1 U2 U3 ...              (W/2 × H/2 字节)
    [V 平面] V0 V1 V2 V3 ...              (W/2 × H/2 字节)
    格式平面顺序说明
    I420 (YUV420P)Y → U → VFFmpeg 默认,H.264 编码器标准输入
    YV12Y → V → UU/V 平面顺序相反
    NV12Y → UV 交错Y 平面 + UV 交错平面(半平面格式)
    NV21Y → VU 交错Y 平面 + VU 交错平面(Android 相机默认)
    YUV422 Planar 格式内存布局详解
    图 15:YUV422 Planar 格式内存布局详解。以 8×2 像素的图像为例,Y 平面存储全部 16 个亮度值(Y00–Y17),U 平面存储 8 个色度值(每行 4 个,水平减半),V 平面存储 8 个色度值。三个平面在内存中连续排列但各自独立。YUV422 Planar(也称 YUV422P)的总数据量为 W×H + W/2×H + W/2×H = W×H×2 字节,是 4:2:0(W×H×1.5 字节)的 4/3 倍。广播级视频采集卡和专业编码器常用此格式。

    Planar 格式的优势是每个分量独立存储,编码器可以直接访问 Y 平面做亮度分析、访问 U/V 平面做色度处理,无需分离操作。

    H.264 编码器使用哪种格式?

    绝大多数 H.264 编码器(x264、OpenH264、硬件编码器)使用 Planar 格式(I420/YUV420P)作为输入:

    1. 编码器需要独立处理 Y、U、V 分量(不同的预测模式、量化参数)

    2. Planar 格式的内存访问模式更适合 SIMD 优化(一次处理一行 Y 值)

    3. 4:2:0 子采样下,U/V 平面的大小只有 Y 的 1/4,Planar 格式天然适配

    如果输入是 Packed 格式(如摄像头输出的 YUYV),编码器需要先做格式转换(Packed → Planar),这一步通常由 libswscale(FFmpeg)或硬件 ISP 完成。

    专题五
    帧的分类:I 帧、P 帧、B 帧
    三种帧类型

    视频编码器将帧分为三种类型,每种类型使用不同的编码策略:

    帧类型全称编码方式特点
    I 帧Intra-coded仅帧内编码(类似 JPEG)独立解码,文件最大
    P 帧Predicted帧间预测(参考前面的帧)文件较小,需要参考帧
    B 帧Bi-directional双向预测(参考前后帧)文件最小,压缩比最高
    I 帧(Intra Frame)

    I 帧只使用帧内预测,不参考其他帧。它是随机访问的入口点——解码器可以从任意 I 帧开始独立解码。I 帧的压缩比最低(约 10–20 倍),但它是整个 GOP 的"锚点"。

    P 帧(Predicted Frame)

    P 帧参考前面的帧(前向参考),通过运动估计找到最佳匹配块,只编码残差。P 帧的压缩比约为 I 帧的 2–3 倍。

    B 帧(Bi-directional Frame)

    B 帧同时参考前面和后面的帧(双向参考),选择最优的预测方向。B 帧的压缩比最高,但需要额外的帧缓冲区,且增加了编码延迟(因为需要等待后续帧)。

    帧类型与压缩效率

    一个典型的帧大小对比(1080p 视频,中等质量):

    帧类型典型大小压缩比
    I 帧50–150 KB~15 倍
    P 帧10–40 KB~50 倍
    B 帧3–15 KB~100 倍

    这就是为什么视频编码器要尽可能多地使用 P 帧和 B 帧,而只在必要时插入 I 帧。

    IDR 帧

    IDR(Instantaneous Decoder Refresh)帧是一种特殊的 I 帧。它与普通 I 帧的区别:

    • 普通 I 帧:后续帧可能参考 IDR 帧之前的帧
    • IDR 帧:解码器在遇到 IDR 帧时清空所有参考帧缓冲区,后续帧只能参考 IDR 帧及其之后的帧

    IDR 帧是真正的随机访问点。在流媒体应用中,每个 GOP 的开头通常是一个 IDR 帧。

    专题六
    图像组(GOP)和层结构
    GOP(Group of Pictures)

    GOP 定义了 I、P、B 帧的排列模式。一个典型的 GOP 结构:

    IDR B B P B B P B B P B B I B B P B B P

    GOP 参数

    • GOP 长度(两个 I 帧之间的帧数):通常 12–60 帧
    • GOP 结构(I/P/B 的排列模式):如 IBBPBBPBBPBB

    GOP 长度的权衡

    GOP 长度优势劣势
    短(12–15 帧)随机访问快、错误恢复快压缩比低(I 帧占比大)
    长(60–300 帧)压缩比高随机访问慢、错误传播严重

    流媒体通常使用较短的 GOP(2–4 秒),以支持快速 seek 和错误恢复。存储场景可以使用更长的 GOP。

    H.264 的层结构

    H.264 标准在架构上分为两层:

    VCL(Video Coding Layer)

    视频编码层,负责核心的压缩工作:帧内/帧间预测、变换、量化、熵编码。VCL 输出的是编码后的视频数据

    NAL(Network Abstraction Layer)

    网络抽象层,负责将 VCL 数据打包为适合不同网络传输的格式。NAL 是 H.264 相比之前标准的一个重要创新——它将编码核心与传输格式解耦,使同一个编码流可以在不同网络环境中使用。

    视频数据 → VCL(压缩编码) → NAL 单元 → 传输/存储
                                        ↓
                              RTP/MP4/TS/FLV...
    NAL 单元结构

    每个 NAL 单元由一个头部载荷组成:

    字段大小含义
    forbidden_zero_bit1 bit必须为 0
    nal_ref_idc2 bitsNAL 重要性指示(00=可丢弃,11=最重要)
    nal_unit_type5 bitsNAL 单元类型

    常见的 NAL 单元类型

    类型值名称含义
    1Non-IDR slice非 IDR 帧的片数据
    5IDR sliceIDR 帧的片数据
    6SEI补充增强信息
    7SPS序列参数集(分辨率、帧率等)
    8PPS图像参数集(量化参数、熵编码模式等)
    9Access unit delimiter访问单元分隔符

    SPS 和 PPS 是 H.264 码流中的关键元数据。解码器需要先收到 SPS 和 PPS 才能正确解码视频数据。

    码流层次结构:SODB → RBSP → EBSP → NAL Unit

    H.264 码流从编码器输出到最终传输,经历四层封装。理解这四层结构是解析 H.264 码流的基础。

    四层结构总览
    编码器输出
      ↓
    SODB (String of Data Bits)        ← 原始比特串
      ↓ + rbsp_trailing_bits
    RBSP (Raw Byte Sequence Payload)  ← 字节对齐的原始载荷
      ↓ + emulation prevention bytes
    EBSP (Encapsulated Byte Sequence Payload) ← 防竞争字节插入后
      ↓ + NAL Header
    NAL Unit                          ← 完整的 NAL 单元
      ↓ + Start Code (0x000001 / 0x00000001)
    H.264 Bitstream                    ← 最终码流
    SODB(String of Data Bits)

    SODB 是编码器输出的最原始的比特串——熵编码(CAVLC 或 CABAC)后的直接结果。它是一串 0 和 1,长度不一定是 8 的倍数。

    例如,编码完一个宏块后,SODB 可能是这样的:

    1 010 011 00100 1 ...  (长度可能是 17 bit)

    SODB 本身不能直接作为字节流传输,因为它不是字节对齐的。

    RBSP(Raw Byte Sequence Payload)

    RBSP 是在 SODB 末尾添加 rbsp_trailing_bits 使其字节对齐后的结果:

    SODB:  1 010 011 00100 1           (17 bit)
                  ↓
    RBSP:  10100110 01001 100          (加 trailing bits: 1 + 填充 0)
                  ↓
    字节:  0xA6     0x4C    0x80        (3 字节)

    rbsp_trailing_bits 的规则:

    1. 先加一个 1 bit

    2. 然后加 0 bit 直到总长度是 8 的倍数

    3. 解码器读到这个 1 后面的 0 就知道 SODB 已经结束

    EBSP(Encapsulated Byte Sequence Payload)

    EBSP 是 RBSP 经过防竞争字节插入(Emulation Prevention)后的结果。这是 H.264 码流中一个容易被忽略但非常重要的机制。

    为什么需要防竞争字节?

    H.264 码流使用 起始码(Start Code)来分隔 NAL 单元:

    • 0x000001(3 字节):图像内分隔
    • 0x00000001(4 字节):序列级分隔

    问题在于:视频数据是随机的,编码后的比特流中可能恰好出现 0x000001,这会导致解码器误认为是 NAL 单元边界,造成解析错误。

    防竞争字节插入规则

    编码器在 RBSP 中扫描,当遇到以下序列时,在第三个字节前插入 0x03

    RBSP 中的序列插入后说明
    0x0000000x00000300插入 0x03
    0x0000010x00000301插入 0x03
    0x0000020x00000302插入 0x03
    0x0000030x00000303插入 0x03

    示例

    RBSP:  ... 00 00 01 ...           ← 可能被误认为起始码
                  ↓
    EBSP:  ... 00 00 03 01 ...       ← 插入 0x03 后不再匹配起始码

    解码器在解析时执行逆操作:遇到 0x000003 就删除 0x03,还原出 RBSP。

    NAL Unit(最终封装)

    在 EBSP 前面加上 NAL 头部(1 字节)就构成了完整的 NAL 单元:

    NAL Header (1 byte) + EBSP
      ↓
    forbidden_zero_bit (1 bit) | nal_ref_idc (2 bits) | nal_unit_type (5 bits)

    多个 NAL Unit 之间用起始码分隔,构成最终的 H.264 码流:

    0x00000001 [NAL Header][EBSP] 0x00000001 [NAL Header][EBSP] ...
    ↑ 起始码      ↑ 一个 NAL Unit      ↑ 起始码      ↑ 另一个 NAL Unit
    解码时的逆向流程
    H.264 码流
      ↓ 找起始码,分割 NAL Unit
    NAL Unit
      ↓ 去掉 NAL Header
    EBSP
      ↓ 删除防竞争字节 (0x000003 → 0x0000)
    RBSP
      ↓ 去掉 rbsp_trailing_bits
    SODB
      ↓ 熵解码 (CAVLC / CABAC)
    编码数据 → 语法元素 (mv, residual, mb_type, ...)
    AnnexB vs AVCC

    H.264 码流有两种封装格式,起始码的使用方式不同:

    格式全称分隔方式典型应用
    AnnexBByte Stream Format起始码 (0x000001 / 0x00000001)TS 流、裸流文件 (.264 / .h264)
    AVCCAVCC Box Format长度前缀 (4 字节长度)MP4 / fMP4 文件

    AnnexB 使用起始码分隔,因此需要防竞争字节。AVCC 使用长度前缀分隔,不需要起始码,因此不需要防竞争字节

    SPS(Sequence Parameter Set,序列参数集)
    SPS 是什么?

    SPS 是 H.264 码流中最高级别的参数集,包含了解码整个视频序列所需的全局参数。一个 SPS 适用于整个视频序列(从开始到结束,或直到新的 SPS 出现)。

    SPS 包含的关键参数
    参数含义示例值
    profile_idcProfile 标识66=Baseline, 77=Main, 100=High
    level_idcLevel 标识30=Level 3.0, 40=Level 4.0
    pic_width_in_mbs_minus1图像宽度(宏块数 - 1)119 → 120 宏块 → 1920 像素
    pic_height_in_map_units_minus1图像高度(宏块数 - 1)67 → 68 宏块 → 1088 像素
    log2_max_frame_num_minus4帧号最大值决定 frame_num 的比特数
    max_num_ref_frames最大参考帧数1–16
    frame_mbs_only_flag是否逐行扫描1=逐行, 0=支持隔行
    bit_depth_luma_minus8亮度位深 - 80=8-bit, 2=10-bit
    bit_depth_chroma_minus8色度位深 - 80=8-bit, 2=10-bit
    vui_parameters_present_flag是否包含 VUI 参数VUI 包含帧率、色域等信息
    SPS 的 ID 机制

    每个 SPS 有一个 seq_parameter_set_id(0–31),允许最多 32 个不同的 SPS 同时存在。PPS 通过引用 SPS ID 来关联对应的 SPS。

    这在实际应用中很有用:例如一个码流可以同时包含低分辨率和高分辨率的编码参数,解码器根据需要选择对应的 SPS。

    VUI(Video Usability Information)

    SPS 可选包含 VUI 参数,提供辅助显示信息

    VUI 参数含义作用
    aspect_ratio_info宽高比4:3、16:9、1:1 等
    video_signal_type视频信号类型PAL/NTSC、全范围/有限范围
    colour_primaries色域标准BT.601、BT.709、BT.2020
    transfer_characteristics伽马/传输函数BT.709、sRGB、PQ、HLG
    timing_info帧率信息num_units_in_tick / time_scale

    VUI 不影响解码过程,但影响显示效果。缺少 VUI 时,播放器可能使用错误的色彩空间或帧率。

    PPS(Picture Parameter Set,图像参数集)
    PPS 是什么?

    PPS 包含了解码单帧图像所需的参数。一个 PPS 可以被多帧引用,不同的帧可以使用不同的 PPS。

    PPS 包含的关键参数
    参数含义示例值
    pic_parameter_set_idPPS 的 ID0–255
    seq_parameter_set_id引用的 SPS ID0–31
    entropy_coding_mode_flag熵编码模式0=CAVLC, 1=CABAC
    num_ref_idx_l0_default_active_minus1List0 默认参考帧数 - 1通常 0–3
    num_ref_idx_l1_default_active_minus1List1 默认参考帧数 - 1B 帧使用
    pic_init_qp_minus26初始 QP 偏移-26 到 +25
    deblocking_filter_control_present_flag是否可控制环路滤波1=Slice 可控制滤波开关
    redundant_pic_cnt_present_flag是否支持冗余片错误恢复用
    PPS 的核心作用

    1. 选择熵编码模式:PPS 决定该帧使用 CAVLC 还是 CABAC——这是编码效率的关键决策

    2. 初始 QP 设置:PPS 设定帧的基准量化参数,Slice 层可以在此基础上调整

    3. 参考帧数量:PPS 设定默认的参考帧数量,Slice 层可以覆盖

    为什么需要参数集?

    在 H.264 之前的标准(如 MPEG-2)中,序列级参数(分辨率、帧率等)被嵌入到每一帧的头部。这导致:

    1. 冗余:每一帧都重复传输相同的参数

    2. 不灵活:参数变化时需要重新同步

    3. 不可靠:如果某一帧的参数丢失,后续帧无法解码

    H.264 的参数集设计解决了这些问题:

    优势 1:减少冗余

    SPS/PPS 只需在码流开始时传输一次(或参数变化时更新),后续帧通过 ID 引用即可。每个 Slice 头部只需 1–2 个字节指定 PPS ID,而不是重复传输所有参数。

    优势 2:带外传输(Out-of-Band)

    SPS/PPS 可以通过独立于视频数据的通道传输:

    • 带内(In-Band):SPS/PPS 作为 NAL 单元嵌入码流中,在每个 IDR 帧前重复发送
    • 带外(Out-of-Band):SPS/PPS 通过 SDP(Session Description Protocol)在会话建立时单独传输

    带外传输在实时通信(WebRTC、RTSP)中非常常见——SDP 协商时就交换了 SPS/PPS,视频数据包不需要携带这些参数。

    优势 3:容错性

    如果 SPS/PPS 在传输中丢失,解码器可以等待下一个 IDR 帧(通常会重新发送 SPS/PPS)。即使丢失了一帧的 SPS/PPS,之前的 SPS/PPS 仍然有效,不会导致整个序列无法解码。

    SPS/PPS 的传输时机
    场景传输方式说明
    文件存储(MP4)存储在 moov box 中文件头包含 SPS/PPS,播放器启动时读取
    流媒体(HLS/DASH)每个片段开头每个 TS/fMP4 片段开头包含 SPS/PPS NAL
    实时通信(WebRTC)SDP 带外传输会话建立时通过 SDP 交换,视频包不携带
    RTSP/RTPSDP + 带内重复SDP 协商 + 每个 IDR 帧前重复发送
    SPS/PPS/Slice 的层级关系

    H.264 码流的参数层级结构:

    SPS (序列参数集)
      ├── 分辨率、帧率、Profile/Level
      ├── 最大参考帧数
      ├── VUI(色域、伽马、宽高比)
      │
      └── PPS (图像参数集)
            ├── 熵编码模式(CAVLC/CABAC)
            ├── 初始 QP
            ├── 参考帧数量
            │
            └── Slice (片数据)
                  ├── Slice 类型(I/P/B)
                  ├── QP 偏移
                  ├── 宏块数据(预测模式、MV、残差系数)

    层级引用关系

    • 一个 SPS 可被多个 PPS 引用(通过 seq_parameter_set_id)
    • 一个 PPS 可被多个 Slice 引用(通过 pic_parameter_set_id)
    • 一个 Slice 属于一帧,一帧包含 1 到多个 Slice
    Slice 结构

    一帧可以被划分为多个 Slice(片),每个 Slice 独立编码,包含整数个宏块:

    • I Slice:只含帧内编码宏块
    • P Slice:含帧内和帧间编码宏块(前向预测)
    • B Slice:含帧内和帧间编码宏块(双向预测)

    Slice 的作用:

    1. 错误恢复:一个 Slice 的解码错误不会传播到其他 Slice

    2. 并行编码:不同 Slice 可以并行处理

    3. MTU 适配:Slice 大小可以适配网络 MTU(最大传输单元)

    专题七
    帧内编码:16×16 宏块预测
    帧内预测的基本思想

    帧内预测利用同一帧内相邻像素的空间相关性来预测当前块的值。与 JPEG 的独立 DCT 不同,H.264 的帧内预测会参考已编码的相邻块,只编码预测残差。

    H.264 支持两种粒度的帧内预测:

    • 16×16 亮度块:4 种预测模式(适合平坦区域)
    • 4×4 亮度块:9 种预测模式(适合细节丰富区域)
    16×16 帧内预测模式

    16×16 亮度块支持 4 种预测模式:

    模式名称预测方向适用场景
    0Vertical从上方像素垂直复制水平纹理
    1Horizontal从左侧像素水平复制垂直纹理
    2DC上方+左侧像素的平均值平坦区域
    3Plane线性平面拟合渐变区域
    Plane 模式是最复杂的 16×16 模式。它假设像素值在水平和垂直方向上都线性变化,用一个平面函数拟合:
    $$P(x, y) = \text{clip}\left(\frac{H + V + a \cdot (x - 7) + b \cdot (y - 7) + 16}{32}\right)$$

    其中 $a$$b$ 分别从上方和左侧的边界像素梯度计算得到。

    色度帧内预测

    8×8 色度块(Cb 和 Cr)支持 4 种预测模式,与 16×16 亮度的 4 种模式相同:DC、Horizontal、Vertical、Plane。

    色度预测模式独立于亮度预测模式选择。编码器对色度单独做率失真优化(RDO),选择最优模式。

    专题八
    帧内编码:4×4 子块预测
    4×4 帧内预测模式

    对于细节丰富的区域,16×16 的预测粒度过粗。H.264 支持将 16×16 宏块划分为 16 个 4×4 子块,每个子块独立选择预测模式。

    4×4 亮度块支持 9 种预测模式

    模式编号名称预测方向
    0Vertical垂直(上方像素复制)
    1Horizontal水平(左侧像素复制)
    2DCDC(上方+左侧平均)
    3Diagonal Down-Left左下对角线
    4Diagonal Down-Right右下对角线
    5Vertical-Right右偏垂直
    6Horizontal-Down下偏水平
    7Vertical-Left左偏垂直
    8Horizontal-Up上偏水平
    预测方向的几何含义

    9 种模式对应 8 个方向 + 1 个 DC 模式。每个 4×4 块使用上方和左侧已编码的像素作为参考:

    参考像素布局(4×4 块):
    
      M A B C D E F G H    ← 上方参考像素
    L . . . .              ← 当前 4×4 块
    K . . . .
    J . . . .
    I . . . .
    • 模式 0(Vertical):用 A,B,C,D 垂直复制到每列
    • 模式 1(Horizontal):用 I,J,K,L 水平复制到每行
    • 模式 2(DC):用上方和左侧像素的平均值填充整个块
    • 模式 3–8:沿不同对角线方向插值
    模式选择:率失真优化

    编码器对每种预测模式计算率失真代价(Rate-Distortion Cost):

    $$J = D + \lambda \cdot R$$

    其中:

    • $D$ 是失真(通常用 SSE 或 SATD)
    • $R$ 是编码该模式所需的比特数
    • $\lambda$ 是拉格朗日乘子,由 QP 决定

    编码器选择 $J$ 最小的模式。这就是率失真优化(RDO)——在压缩率和失真之间找到最优平衡。

    专题九
    帧间预测:运动估计与运动补偿
    帧间预测的核心思想

    帧间预测是视频压缩中贡献最大的技术,约占总压缩效率的 50%。

    基本思想:

    1. 运动估计:在参考帧中搜索与当前块最匹配的区域,记录偏移量(运动矢量 MV)

    2. 运动补偿:用参考帧中匹配区域的像素作为当前块的预测值

    3. 残差编码:只编码当前块与预测值之间的差值

    如果运动估计准确,残差的能量远小于原始像素值,可以用很少的比特编码。

    灵活的宏块划分

    H.264 以 16×16 宏块为基本编码单元,但每个宏块可以灵活划分为更小的块进行运动估计:

    帧间预测的宏块划分

    模式划分方式块数MV 数
    16×16不划分11
    16×8水平划分22
    8×16垂直划分22
    8×8四等分44
    8×8 子划分每个 8×8 可再分为 8×4, 4×8, 4×4最多 16最多 16

    这种灵活划分的意义:

    • 平坦区域:使用大块(16×16),减少运动矢量开销
    • 细节和运动复杂区域:使用小块(4×4),提高预测精度

    编码器通过 RDO 自动选择最优的划分模式。

    块匹配算法

    最常用的运动估计方法是块匹配(Block Matching)。对于当前帧中的每个块,在参考帧的搜索窗口内寻找最佳匹配:

    $$\text{最佳 MV} = \arg\min_{(dx, dy)} \sum_{(x,y) \in \text{block}} |I_{\text{curr}}(x,y) - I_{\text{ref}}(x+dx, y+dy)|$$
    匹配准则
    准则公式精度速度
    SAD$\sumI_c - I_r$最快
    SATD$\sum\text{HAD}(I_c - I_r)$
    MSE$\frac{1}{N^2}\sum (I_c - I_r)^2$最慢
    搜索算法
    • 全搜索:穷举所有可能位置,精度最高但计算量巨大
    • 三步搜索(TSS):步长从大到小分三步搜索
    • 菱形搜索(DS):利用 MV 通常接近零的特点,优先搜索中心附近
    亚像素运动估计

    真实的运动往往不是整像素的整数倍。H.264 支持 1/4 像素精度的运动估计:

    • 半像素插值:使用 6-tap FIR 滤波器在整像素之间插值
    • 1/4 像素插值:在半像素之间线性插值
    $$\text{半像素位置 } b = \text{clip}\left(\frac{E - 5F + 20G + 20H - 5I + J + 16}{32}\right)$$

    其中 E,F,G,H,I,J 是整像素位置的亮度值。这个 6-tap 滤波器的系数 [1, -5, 20, 20, -5, 1] / 32 近似于 sinc 插值。

    亚像素插值显著提高了运动估计的精度,减少了残差能量。

    多参考帧

    H.264 支持从多个参考帧中选择最佳匹配,而不仅仅是前一帧:

    • 物体遮挡/显露:被遮挡的区域可能在更早的帧中可见
    • 周期性运动:物体可能回到之前某个位置
    • 场景切换:编码器可以选择与当前帧最相似的参考帧

    参考帧列表最多支持 16 帧。实际应用中通常使用 2–5 帧参考。

    加权预测与直接模式
    加权预测(Weighted Prediction)

    P 帧和 B 帧的预测值可以是多个参考帧的加权平均:

    $$\hat{P} = w_1 \cdot \text{Ref}_1 + w_2 \cdot \text{Ref}_2 + w_o$$

    加权预测对于淡入淡出场景特别有效。

    直接模式(Direct Mode)

    B 帧中的直接模式不解码 MV,而是从空间相邻块或时域相邻帧推导:

    • 时域直接:从最近的参考帧中推断当前块的 MV
    • 空域直接:从前一编码块的空间邻居推断

    直接模式不需要传输 MV,大幅节省比特。

    运动矢量差分编码(MVD)

    H.264 对 MV 做差分编码:

    $$\text{MVD} = \text{MV}_{\text{current}} - \text{MV}_{\text{predicted}}$$

    预测 MV 来自左侧、上方、左上方的相邻块。

    专题十
    DCT 变换和量化
    整数 DCT 变换

    H.264 使用 4×4 整数 DCT 变换(不是标准的浮点 DCT)。这是 H.264 的一个重要创新:

    $$Y = C_f X C_f^T$$

    其中 $C_f$ 是整数变换矩阵:

    $$C_f = \begin{bmatrix} 1 & 1 & 1 & 1 \\ 2 & 1 & -1 & -2 \\ 1 & -1 & -1 & 1 \\ 1 & -2 & 2 & -1 \end{bmatrix}$$

    反变换矩阵:

    $$C_i = \begin{bmatrix} 1 & 1 & 1 & 1 \\ 1 & \frac{1}{2} & -\frac{1}{2} & -1 \\ 1 & -1 & -1 & 1 \\ \frac{1}{2} & -1 & 1 & -\frac{1}{2} \end{bmatrix}$$
    整数变换的优势
    • 精确一致:编解码器之间不存在浮点精度差异(反变换完全精确)
    • 计算高效:只需整数加法和移位操作
    • 硬件友好:适合 ASIC/FPGA 实现
    8×8 变换(High Profile)

    H.264 High Profile 额外支持 8×8 整数 DCT 变换,适用于高分辨率视频。8×8 变换在高频细节保留方面优于 4×4 变换,但计算量更大。

    编码器可以自适应选择 4×4 或 8×8 变换(通过 RDO)。

    Hadamard 变换(DC 系数)

    对于帧内 16×16 模式,H.264 对 16 个 4×4 块的 DC 系数再做一次 4×4 Hadamard 变换

    $$H_4 = \begin{bmatrix} 1 & 1 & 1 & 1 \\ 1 & 1 & -1 & -1 \\ 1 & -1 & -1 & 1 \\ 1 & -1 & 1 & -1 \end{bmatrix}$$

    Hadamard 变换进一步压缩了 DC 系数之间的相关性。

    量化

    H.264 使用标量量化器:

    $$Z_{ij} = \text{round}\left(\frac{Y_{ij}}{Q_{\text{step}}}\right)$$
    量化参数(QP)

    量化步长 $Q_{\text{step}}$ 由量化参数 QP(0–51)控制:

    QP$Q_{\text{step}}$效果
    00.625最高质量,最低压缩
    122.5高质量
    2410中等质量
    3640低质量,高压缩
    51224最低质量,最高压缩

    QP 每增加 6,量化步长翻倍。 这意味着 QP 增加 6 时,码率大约减半。

    专题十一
    熵编码:CAVLC 与 CABAC
    熵编码的作用

    熵编码是压缩流水线的最后一步。它消除统计冗余——编码后的符号(量化系数、运动矢量、宏块类型等)在概率分布上不均匀,出现频率高的符号用短码字,频率低的用长码字。

    H.264 支持两种熵编码模式:

    模式全称Profile效率复杂度
    CAVLCContext-Adaptive VLCBaseline
    CABACContext-Adaptive Binary Arithmetic CodingMain/High

    CABAC 比 CAVLC 节省约 10%–15% 的比特,但计算复杂度显著更高。

    指数哥伦布编码(Exponential-Golomb Coding)
    指数哥伦布码是什么?

    指数哥伦布码(Exp-Golomb Code)是 H.264 中用于编码语法元素(Syntax Elements)的变长编码方案。它是哥伦布码(Golomb Code)的推广,对小值非常高效——值越小码字越短,值越大码字越长。

    H.264 中大量语法元素使用指数哥伦布码编码:

    • 宏块类型(mb_type)
    • 运动矢量差值(MVD)
    • 参考帧索引(ref_idx)
    • 量化参数差值(delta_qp)
    • CAVLC 中的 TotalCoeffs、TrailingOnes 等
    编码原理

    $k$-阶指数哥伦布码的编码步骤(H.264 使用 $k=0$,即 0 阶 Exp-Golomb):

    1. 将待编码值 $v$ 加 1:$v' = v + 1$

    2. 将 $v'$ 写为二进制

    3. 在二进制表示前面添加 $(\text{bit_length} - 1)$ 个前导零

    0 阶 Exp-Golomb 码表
    $v$$v+1$(二进制)码字码长
    0111
    1100103
    2110113
    3100001005
    4101001015
    5110001105
    6111001115
    7100000010007
    码字结构

    每个 Exp-Golomb 码字由三部分组成:

    [前导零] [1] [信息位]
    • 前导零:数量 = 信息位的位数
    • 1:分隔符,标记信息位的开始
    • 信息位$v+1$ 的二进制表示去掉最高位的 1
    为什么适合 H.264?

    H.264 中的语法元素具有明显的小值偏向

    • 运动矢量差值(MVD)大多接近零(运动通常很平缓)
    • 宏块类型中,SKIP 模式(值=0)在 P 帧中占比很高
    • 参考帧索引通常选择最近的帧(值小)

    Exp-Golomb 码对值 0 只用 1 bit,对值 1–2 用 3 bits,对值 3–6 用 5 bits——完美匹配了小值高频的分布特性。

    四种变体

    H.264 定义了四种 Exp-Golomb 编码方式,用于不同取值范围的语法元素:

    变体名称适用场景映射规则
    ue(v)无符号 Exp-Golomb非负整数:宏块类型、参考帧索引code_num = v
    se(v)有符号 Exp-Golomb可正可负:MVD、delta_qpv > 0 → code_num = 2v-1
    v ≤ 0 → code_num = -2v
    te(v)截断 Exp-Golomb有上限的整数(0 ~ N)N=1 时 1 bit 反转;否则同 ue(v)
    me(v)映射 Exp-Golombcoded_block_pattern(CBP)查表映射(Inter/Intra 模式各一张表)
    ue(v) 详解:无符号 Exp-Golomb

    最简单的形式,直接对非负整数 $v$ 进行 0 阶 Exp-Golomb 编码。H.264 中最常用的语法元素:

    语法元素含义典型值分布
    mb_type宏块编码模式SKIP(值=0)占 P 帧 60%+
    ref_idx参考帧索引0 最常见(选最近帧)
    mb_qp_deltaQP 偏移量小值高频,偶尔大跳变
    se(v) 详解:有符号 Exp-Golomb

    有符号 Exp-Golomb 的核心思想是将正负整数交替映射到非负整数上,保证绝对值小的数映射到小 code_num:

    原始值 $v$映射规则code_num码字
    0-2×001
    12×1-11010
    -1-2×(-1)2011
    22×2-1300100
    -2-2×(-2)400101
    32×3-1500110
    -3-2×(-3)600111
    为什么用交替映射而不是先正后负?

    交替映射(zigzag 映射)保证了绝对值相同的正负数 code_num 相邻(如 1→1, -1→2;2→3, -2→4)。这样在解码时,只需读出一个 code_num,就能通过简单的奇偶判断还原原始值:

    if code_num is odd:  v = (code_num + 1) / 2
    if code_num is even: v = -(code_num / 2)
    se(v) 的典型应用——运动矢量差(MVD)

    运动矢量通常围绕零波动(运动平缓场景),MVD 的分布近似拉普拉斯分布:

    • MVD=0 的概率约 40–60%(用 1 bit)
    • MVD=±1 的概率约 15–20%(用 3 bits)
    • MVD=±2 的概率约 5–10%(用 5 bits)
    te(v) 详解:截断 Exp-Golomb

    te(v) 用于取值范围受限的语法元素(0 ~ range)。它的特殊之处在于当 range=1 时只用 1 bit 编码:

    • range=1(即值只能是 0 或 1):直接用 1 - v 编码。即 0→1, 1→0。只花 1 bit。
    • range > 1:与 ue(v) 相同,但最大值不能超过 range。

    te(v) 的典型应用:

    • field_coding_flag:逐行 vs 隔行编码标志(只有 0/1 两种可能)
    • transform_size_8x8_flag:4×4 vs 8×8 变换标志
    me(v) 详解:映射 Exp-Golomb

    me(v) 是最特殊的一种——它不是直接计算,而是查表映射。H.264 为 coded_block_pattern(CBP)定义了两张映射表:

    • Intra 模式 CBP 表:64 个条目,每个 CBP 值映射到一个 code_num
    • Inter 模式 CBP 表:48 个条目

    CBP(Coded Block Pattern)表示宏块中哪些 4×4 子块有非零残差系数。由于 CBP 的取值不是均匀分布的(某些模式极高频出现),H.264 标准委员会通过统计实际视频数据,手工设计了这两张最优映射表。

    me(v) 的设计哲学:当统计特性已知且固定时,查表映射可以比数学公式更精确地匹配实际分布

    📺 视频讲解推荐

    Redknot-乔红 (2022). 从代码实现角度详细讲解 Exp-Golomb 编码/解码的完整流程,包含 ue(v)、se(v) 的编解码逻辑和 C 语言实现。配套代码:EyerH264Decoder

    CAVLC(上下文自适应可变长编码)

    CAVLC 用于 Baseline Profile。它的核心思想是根据已编码的语法元素动态选择不同的 VLC 表

    残差系数编码流程

    1. TotalCoeffs:编码非零系数的总数

    2. TrailingOnes:编码末尾 ±1 的个数(最多 3 个)

    3. Level:编码每个非零系数的值(从高频到低频)

    4. TotalZeros:编码零的总数

    5. RunBefore:编码每个非零系数前的零的个数

    CAVLC 利用了 DCT 系数的两个统计特性:

    • 高频系数大多为零(zigzag 扫描后零集中在末尾)
    • 非零系数的值通常较小(±1 最常见)
    CABAC(上下文自适应二进制算术编码)

    CABAC 是 H.264 最高效的熵编码模式,用于 Main Profile 和 High Profile。

    CABAC 的工作流程Step 1:二值化(Binarization)

    将非二进制语法元素转换为二进制串(bin string)。不同的语法元素使用不同的二值化方案:

    语法元素二值化方法
    宏块类型定长码
    运动矢量差值指数哥伦布码
    量化系数一元码 + 定长码
    Step 2:上下文建模(Context Modeling)

    根据相邻已编码元素的状态选择上下文模型。每个上下文模型维护一个概率估计:

    • 例如,编码当前块的非零系数个数时,参考上方和左侧块的非零系数个数来选择上下文模型
    • H.264 定义了约 460 个上下文模型
    Step 3:算术编码(Arithmetic Coding)

    使用选定的上下文模型的概率估计进行二进制算术编码。算术编码的核心思想是将整个符号序列映射为 [0, 1) 区间内的一个实数。

    Step 4:概率更新(Probability Update)

    每编码一个 bin,更新对应上下文模型的概率估计。H.264 使用查表法(64 个概率状态)快速更新。

    CABAC vs CAVLC 的效率对比
    测试序列CAVLC 码率CABAC 码率节省
    Foreman CIF512 kbps445 kbps13%
    Mobile CIF1024 kbps890 kbps13%
    720p HD4 Mbps3.4 Mbps15%

    CABAC 的优势在高分辨率和高码率下更明显。

    专题十二
    环路滤波、Profile 与 Level
    自适应去块滤波(Deblocking Filter)

    H.264 引入了环路内自适应去块滤波(In-loop Deblocking Filter),这是 H.264 相比之前标准的一个重要改进。

    为什么叫"环路内"?

    去块滤波在编码环路内部运行,滤波后的帧作为后续帧的参考帧。这意味着:

    1. 解码端和编码端使用完全相同的滤波(保证一致性)

    2. 滤波后的参考帧更干净,提高了后续帧的预测精度

    滤波强度

    对每个 4×4 块边界,根据以下因素确定滤波强度(Boundary Strength, Bs):

    Bs 值条件滤波强度
    4帧内编码块边界最强
    3
    2帧间编码块,有编码残差中等
    1帧间编码块,无残差但 MV 差异大
    0帧间编码块,无残差且 MV 差异小不滤波

    滤波过程对边界两侧的像素进行平滑,消除块效应(blocking artifacts)。

    Profile(编码工具集)

    H.264 定义了多个 Profile,每个 Profile 是一组编码工具的子集:

    Profile工具集典型应用
    BaselineI/P 帧,CAVLC,无 B 帧视频会议、移动设备
    MainI/P/B 帧,CABAC,隔行扫描数字电视、存储
    Extended数据分区无线传输
    High8×8 变换,量化矩阵,4:2:2/4:4:4蓝光、广播、流媒体
    High 10High + 10-bit专业制作
    High 4:2:2High 10 + 4:2:2广播级
    High 4:4:4High 4:2:2 + 4:4:4无损/近无损

    Baseline Profile 最简单,适合低功耗设备。High Profile 功能最全,是目前使用最多的 Profile。

    Level(性能约束)

    Level 定义了码率、分辨率、帧率等性能上限:

    Level最大码率最大分辨率最大帧率典型应用
    1.064 kbps176×14415fps移动视频通话
    1.3768 kbps352×28830fps低码率视频
    3.010 Mbps720×57630fps标清视频
    3.114 Mbps1280×72030fps720p
    4.020 Mbps2048×102430fps2K
    4.150 Mbps2048×102430fps1080p
    5.0135 Mbps3672×153630fps2K 高帧率
    5.1240 Mbps4096×216030fps4K

    Profile 和 Level 的组合(如 "High@L4.1")完整描述了一个 H.264 码流的编码工具集和性能要求。

    H.264 编码器完整流程回顾
    输入帧(YUV 4:2:0)
        │
        ├─ 宏块划分(16×16 → 可选 8×8 子划分)
        │
        ├─ 帧内预测 或 帧间预测(运动估计 + 运动补偿)
        │   │
        │   ├─ 帧内:4×4(9 种模式)或 16×16(4 种模式)
        │   └─ 帧间:多参考帧 + 1/4 像素精度 + 灵活块划分
        │
        ├─ 残差计算
        │
        ├─ 整数 DCT 变换(4×4 或 8×8)
        │
        ├─ 量化(QP 0–51)
        │
        ├─ 熵编码(CAVLC 或 CABAC)
        │
        ├─ 输出 NAL 单元 → 码流
        │
        └─ 重建路径(用于参考帧):
            反量化 → 反变换 → 重建帧 → 环路滤波 → 参考帧存储

    这就是 H.264 的完整编码流水线。每个环节都经过精心设计,共同实现了相比 MPEG-2 约 50% 的压缩效率提升。

    参考来源

    • Richardson, I. E. G. (2010). The H.264 Advanced Video Compression Standard (2nd ed.). Wiley.
    • ITU-T H.264 (2021). "Advanced Video Coding for Generic Audiovisual Services".
    • Wiegand, T., et al. (2003). "Overview of the H.264/AVC Video Coding Standard". IEEE Transactions on Circuits and Systems for Video Technology, 13(7), 560–576.
    • Marpe, D., Schwarz, H., & Wiegand, T. (2003). "Context-Based Adaptive Binary Arithmetic Coding in the H.264/AVC Compression Standard". IEEE Transactions on Circuits and Systems for Video Technology, 13(7), 620–636.
    • Sullivan, G. J., et al. (2012). "Overview of the High Efficiency Video Coding (HEVC) Standard". IEEE TCSVT, 22(12), 1649–1668.(含 H.264 与 HEVC 对比)
    • 望天空云卷云舒 (2025). H.264视频编码原理系列(抖音合集,12集):从概述、数字视频基础、数据冗余与压缩、RGB到YUV编码、帧分类、图像组与层结构、帧内/帧间预测、DCT变换与量化到熵编码的完整讲解。
    • Redknot-乔红 (2022). 自己动手写 H.264 解码器——指数哥伦布熵编码(B站,41:16)。从 C 语言实现角度详解 Exp-Golomb 编解码流程,配套代码:EyerH264Decoder
    • Redknot-乔红. zzsin.com:视频编解码工具集——YUV Eye(YUV 图像分析)、Codec Eye(视频码流分析)、h265web(Web 端 H.265 播放器)、Shader++(OpenGL Shader 在线编写与视频渲染)、色域空间教学课件等。
    系列导航
    本系列其他文章