一张 4 0 0 0 × 3 0 0 0 4000 × 3000 、每通道 8 bit 的 RGB 照片若直接保存像素,需要 36 MB。一分钟 44.1 kHz、16-bit、双声道 PCM 音频约需 10.6 MB。一段 1 9 2 0 × 1 0 8 0 1920 × 1080 、30 fps、每像素 24 bit 的原始视频,码率更达到约 1.49 Gbit/s。三者看似是不同问题,其实都在问同一件事:decoder 已经能从哪些结构猜到当前 sample,又该把有限的 bits 花在哪些猜不准且重要的误差上?
把图像、音频和视频放在一起讨论,传统信号处理里更常称为 multimedia compression(多媒体压缩) 。近年的「multimodal compression(多模态压缩)」还常指联合压缩文字、视觉、语音等模型表示,目标可能是保留语义而不是还原媒体 sample。本文讨论前一种问题;最后再说明学习式 codec 怎样让两种含义开始相交。
本文先从一条可逆的压缩链出发,再让失真有控制地进入。这样,PNG、JPEG、FLAC、MP3、AAC、Opus、H.264、AV1 和神经 codec 不再是一串格式名称,而是对同一组设计问题的不同回答。
阅读时可以抓住三个问题:为什么还有冗余,怎样让误差可控,以及 decoder 需要知道什么? 前半部分建立 entropy coding、prediction、transform 和 rate–distortion 的共同基础;后半部分再分别讨论图像的空间尺度、音频的听觉与时频结构、视频的运动和参考依赖。推导中的概率表示对一类信号的统计模型,不是说某个固定文件天然带着一个可直接读取的“熵值”。
原始媒体已经是一组离散 samples
相机、麦克风先把连续的光和声变成离散数值。图像 sample 沿空间排列,音频 sample 沿时间排列,视频则同时具有空间和时间轴:
媒体 sample 的坐标 最直接的重复 常见的额外约束 图像 ( 𝑥 , 𝑦 , c h a n n e l ) ( x , y , channel ) 邻近像素与颜色通道相关 随机访问、透明度、颜色管理 音频 ( 𝑡 , c h a n n e l ) ( t , channel ) 相邻时刻、周期与声道相关 延迟、瞬态、听觉 masking 视频 ( 𝑡 , 𝑥 , 𝑦 , c h a n n e l ) ( t , x , y , channel ) 帧内空间结构与帧间运动 seek、参考依赖、播放时序
这里有两个容易混淆的 quantization。采集时的 bit depth 已经把连续振幅量化成整数 sample;有损 codec 随后还会再次量化预测误差或变换系数。Lossless codec 保证恢复输入的离散 samples,不可能反推出采样前已经消失的连续信号。提高 sample rate 或 bit depth 也不会自动改善一个已经失真的来源。
采样率、bit depth 和 dither 分别改变什么? 若连续信号严格带限于 𝐵 B Hz,并以 𝑓 𝑠 > 2 𝐵 f s > 2 B 理想采样,未量化的样本足以确定原信号。DAC 要重建的是这个带限波形;把相邻 samples 画成阶梯,只是一种显示方式。提高采样率主要扩展可表示带宽;提高 bit depth 则减小振幅量化间隔。两者回答不同的问题 (Montgomery, 2013 ) 。
均匀四舍五入也不总产生白噪声。例如量化 step 为 Δ Δ 时,振幅小于 Δ / 2 Δ / 2 的正弦波会全部舍入到零;误差完整保留了输入的周期结构。先加入适当分布、适当幅度的 dither 再量化,可以打散这种结构,使量化后的误差统计更稳定,代价通常是增加总噪声功率。它并不是把音频压缩得更小,而是在固定精度下,用较少的相关失真换取更可控的噪声;这也提醒我们,不能只用一个 MSE 数字描述声音质量 (Montgomery, 2013 ) 。
还要分清四个名字:
Codec / 编码标准 定义合法 bitstream 和 decoder 怎样重建,例如 JPEG、AAC、AV1;
Encoder 实现 在合法方案中搜索,例如 libjpeg-turbo、x264、SVT-AV1;
Container 封装一条或多条媒体轨道、字幕、metadata 与时间戳,例如 MP4、WebM;
传输方式 规定如何交付和切换这些文件或片段,例如 HLS、DASH。
因此,.mp4 不是视频 codec,.m4a 也不是音频 codec。一个 MP4 可以把 H.264 视频与 AAC 音频分别编码,再用时间戳同步;普通视频压缩通常不会把画面和声音交给一个联合 codec。
一条跨媒体的压缩主线
典型 codec 可以拆成五项工作:
选择更合适的表示,例如把 RGB 分成亮度与色度,或把左右声道改写成和与差;
用邻居、历史、另一帧或模型产生 prediction,只编码 residual;
用 transform 把分散的相关性集中到更容易取舍的坐标;
量化 coefficients 或 parameters,在 rate 与 distortion 之间做决定;
用 entropy model 把常见符号写短、罕见符号写长。
图像、音频和视频可以共享同一份双向账本。Decoder 不会猜 encoder 的选择;bitstream 携带必要参数与量化后的符号。具体 codec 可以省略、合并或重新排列部分阶段。
并非每个 codec 都严格按这个顺序,也并非每一步都存在。Lossless codec 不跨越有损量化边界;speech codec 可能直接编码声道模型的参数;学习式 codec 会把多个方框合成一个网络。但这条主线能帮助我们判断:某一步是在改写信息 、舍弃信息 ,还是只在更短地表示信息 。
先做一个完全可逆的压缩器
先看一行整数 samples:
𝑥 = [ 5 2 , 5 3 , 5 4 , 5 5 , 5 5 , 5 6 , 5 7 , 5 7 ] . x = [ 52 , 53 , 54 , 55 , 55 , 56 , 57 , 57 ] .
约定第一个值原样保存,此后都用前一个已经重建的值预测:
𝑒 0 = 𝑥 0 , 𝑒 𝑖 = 𝑥 𝑖 − 𝑥 𝑖 − 1 . e 0 = x 0 , e i = x i − x i − 1 .
得到
𝑒 = [ 5 2 , 1 , 1 , 1 , 0 , 1 , 1 , 0 ] . e = [ 52 , 1 , 1 , 1 , 0 , 1 , 1 , 0 ] .
Decoder 从 ˆ 𝑥 0 = 𝑒 0 x ^ 0 = e 0 开始,重复 ˆ 𝑥 𝑖 = ˆ 𝑥 𝑖 − 1 + 𝑒 𝑖 x ^ i = x ^ i − 1 + e i ,就能精确恢复原序列。Prediction 没有减少元素数量;若仍给每个 residual 固定 8 bit,文件也不会变小。它只把分散的 sample values 改写成集中在 0 和 1 附近的分布。
Prediction 没有删除任何元素,而是把分布集中到 0 和 1;entropy coding 才利用频数差异减少 bits。首项 52 是建立预测所需的 side information,在更大图像中会被许多后续样本摊薄。
Entropy coding 才把这种偏斜分布兑现为较少 bits。概率为 𝑝 ( 𝑠 ) p ( s ) 的符号,其理想码长接近
ℓ ( 𝑠 ) = − l o g 2 𝑝 ( 𝑠 ) , ℓ ( s ) = − log 2 p ( s ) ,
对独立同分布的离散符号,平均码长的理论下界由 entropy 描述;足够长的联合编码可以逼近它:
𝐻 ( 𝑋 ) = − ∑ 𝑠 𝑝 ( 𝑠 ) l o g 2 𝑝 ( 𝑠 ) . H ( X ) = − ∑ s p ( s ) log 2 p ( s ) .
从概率到真正可解码的 bits
短码不能随意分配。如果把三个符号写成 0、1、01,收到 01 时就无法判断它是一个符号还是两个。Prefix code 要求一个完整码字不能是另一个码字的开头,因此 decoder 沿二叉树读到叶子就知道当前符号结束。Huffman coding 从概率最小的两个符号开始合并,逐步建出平均码长最短的二元 prefix tree (Girod, 2012 ) 。
例如,假设 residual 的符号概率如下;这里单独构造一个分布来算码长,不把前面八个 samples 当作准确的总体统计:
符号 概率 一组 Huffman code 对平均码长的贡献 0 0 1 / 2 1 / 2 01 / 2 1 / 2 bit1 1 1 / 4 1 / 4 101 / 2 1 / 2 bit− 1 − 1 1 / 8 1 / 8 1103 / 8 3 / 8 bit2 2 1 / 8 1 / 8 1113 / 8 3 / 8 bit
固定长度需要 2 bit/symbol,这组码的平均长度是 1.75 bit/symbol,恰好等于 entropy。它仍然不能保证每个短文件都变小:还要保存长度、码表或其编号,罕见符号本身甚至比固定长度更长。
若一个二元符号出现概率为 0.99,单符号 Huffman 仍要给两种结果各 1 bit,无法使用接近 0 bit 的理想码长。Arithmetic coding 把整串符号共同表示为一个区间 ,从而摊薄这种整数码长限制 (Girod, 2012a ) 。设 𝑝 ( 𝐴 ) = 3 / 4 , 𝑝 ( 𝐵 ) = 1 / 4 p ( A ) = 3 / 4 , p ( B ) = 1 / 4 ,每次把当前区间的前 3 / 4 3 / 4 分给 𝐴 A ,后 1 / 4 1 / 4 分给 𝐵 B :
已编码前缀 留下的区间 区间宽度 空 [ 0 , 1 ) [ 0 , 1 ) 1 1 𝐴 A [ 0 , 3 / 4 ) [ 0 , 3 / 4 ) 3 / 4 3 / 4 𝐴 𝐴 A A [ 0 , 9 / 1 6 ) [ 0 , 9 / 16 ) 9 / 1 6 9 / 16 𝐴 𝐴 𝐵 A A B [ 2 7 / 6 4 , 3 6 / 6 4 ) [ 27 / 64 , 36 / 64 ) 9 / 6 4 9 / 64
假设两端已知消息长度为 3,就可以用最终区间内的二进制数让 decoder 逐次判断它落在哪个子区间。例如前缀 1000 表示的二进制小数区间 [ 1 / 2 , 9 / 1 6 ) [ 1 / 2 , 9 / 16 ) 完全落在最终区间内。这里 4 bit 还包含短消息的取整与二进制区间对齐成本;长串的区间宽度是各条件概率的乘积,因此所需精度约为 − l o g 2 𝑝 ( 整串 ) − log 2 p ( 整串 ) 。实际 range/arithmetic coder 用有限精度整数和 renormalization,及时输出已经确定的高位,不会真的存一个无限精度小数。消息长度或结束符也必须有约定。
预测降低的是哪一种不确定性
一幅黑白条纹图可能一半是 0、一半是 1,单看直方图与随机黑白噪声一样。但条纹的邻居很有用:若前一个像素为白,下一个多半仍为白。Decoder 已经读过的内容应成为当前概率模型的条件 (Girod, 2012c ) 。
构造一个对称的二状态模型:首个 bit 等概率取 0 或 1,以后每步有 95% 概率保持原值,5% 概率翻转。每个位置单独看都有 𝐻 ( 𝑋 𝑖 ) = 1 H ( X i ) = 1 bit;已知前一个 bit 后,只需说明“保持还是翻转”,平均不确定性变成
𝐻 ( 𝑋 𝑖 ∣ 𝑋 𝑖 − 1 ) = − 0 . 9 5 l o g 2 0 . 9 5 − 0 . 0 5 l o g 2 0 . 0 5 ≈ 0 . 2 8 6 b i t . H ( X i ∣ X i − 1 ) = − 0.95 log 2 0.95 − 0.05 log 2 0.05 ≈ 0.286 bit .
对长度为 𝑛 n 的序列,联合 entropy 是 1 + ( 𝑛 − 1 ) × 0 . 2 8 6 1 + ( n − 1 ) × 0.286 ,不是 𝑛 n 。一般地,先描述第一个符号,再逐个描述在历史已知时的新增信息,就得到 chain rule:
𝐻 ( 𝑋 1 , … , 𝑋 𝑛 ) = 𝑛 ∑ 𝑖 = 1 𝐻 ( 𝑋 𝑖 ∣ 𝑋 1 , … , 𝑋 𝑖 − 1 ) . H ( X 1 , … , X n ) = ∑ i = 1 n H ( X i ∣ X 1 , … , X i − 1 ) .
可逆 prediction 没有降低整串的联合 entropy,而是把这类依赖转成一个简单 entropy coder 也能利用的 residual 分布。另一种做法是直接给原符号建立 conditional probability model;两者都在避免重复描述 decoder 已经知道的事情。
如果实际分布是 𝑝 p ,coder 却按 𝑞 q 分配理想码长,那么平均代价为
𝔼 𝑝 [ − l o g 2 𝑞 ( 𝑋 ) ] = 𝐻 ( 𝑝 ) + 𝐷 K L ( 𝑝 ‖ 𝑞 ) . E p [ − log 2 q ( X ) ] = H ( p ) + D KL ( p ‖ q ) .
右边第二项就是模型失配的额外成本。两端可以从相同的已解码历史更新模型,省去逐次发送概率的费用;但初始状态、更新规则和整数舍入必须一致。把“预测越准越好”改成“对真实符号给出的概率越合适,总码长越短”,才能同时理解传统 context model 和后面的 learned entropy model。
这个例子同时适用于空间和时间。PNG 为每条 scanline 选择可逆 filter,把像素改写成相对左侧、上方或邻域预测的差,再用 DEFLATE 压缩字节流 (World Wide Web Consortium, 2025 ) 。FLAC 把 PCM 分块,可选择 fixed predictor 或 linear predictive coding(LPC),再用 Rice codes 编码通常靠近零的 residual;stereo 还可在左右声道与 mid/side 等可逆表示之间选择 (van Beurden et al., 2024 ) 。
预测器本身也要有成本。若模型参数、模式编号或分块边界占掉的 bits 超过 residual 的节省,就不值得使用。压缩器真正比较的不是「哪个 prediction 最准」,而是
总码长 = 模型与 s i d e i n f o r m a t i o n + r e s i d u a l 的码长 . 总码长 = 模型与 side information + residual 的码长 .
随机噪声难以压缩,原因也由此变得具体:没有一个足够便宜的模型能让它的 residual 明显更简单。
怎样从邻居设计一个线性预测器? 只用前一个 sample 相当于预先指定预测系数为 1。若邻居间的关系没那么强,可以让系数由数据决定。把可用的邻居组成向量 𝐳 z ,先减去各自均值,用 𝐚 ⊤ 𝐳 a ⊤ z 预测当前值 𝑥 x 。
我们希望 residual 𝑒 = 𝑥 − 𝐚 ⊤ 𝐳 e = x − a ⊤ z 的平方尽可能小。如果 residual 还与某个邻居相关,就说明沿那个邻居的方向调整预测还有改善空间。对各个系数求导,把这一条件写出来,得到
𝔼 [ 𝐳 ( 𝑥 − 𝐚 ⊤ 𝐳 ) ] = 0 , 𝔼 [ 𝐳 𝐳 ⊤ ] 𝐚 = 𝔼 [ 𝐳 𝑥 ] . E [ z ( x − a ⊤ z ) ] = 0 , E [ z z ⊤ ] a = E [ z x ] .
这就是线性 least-squares prediction 的 normal equations;covariance 矩阵可逆时可直接求解 (Girod, 2012d ) 。例如当前值与前一值同方差 𝜎 2 σ 2 、相关系数为 𝜌 ρ ,只用前一值时最优系数是 𝑎 = 𝜌 a = ρ ,residual 方差变成 𝜎 2 ( 1 − 𝜌 2 ) σ 2 ( 1 − ρ 2 ) 。取 𝜌 = 0 . 9 ρ = 0.9 ,只剩原方差的 19%。
小方差只是“更容易编码”的一种代理,最终仍需比较真实码长与参数开销。无损实现还要约定确定的整数预测和 rounding,再精确发送差值;有损实现则必须使用 decoder 可重建的历史,后面的音频与视频闭环会继续解释这一点。
从连续的零到 Rice code:怎样把 residual 写成简单整数码 若 residual 经常为零,可以先保存非零值前有多少个零,这就是 run-length coding。黑白文档也可用交替的白色、黑色 run lengths 表示;相邻 scanline 的边界往往相近,还能预测下一行的边界位置。这是把一维重复进一步变成二维依赖,而不是让 entropy coder 猜出整张图。
对靠近零的有符号整数,先用 0 , − 1 , 1 , − 2 , 2 , … ↦ 0 , 1 , 2 , 3 , 4 , … 0 , − 1 , 1 , − 2 , 2 , … ↦ 0 , 1 , 2 , 3 , 4 , … 折叠成非负数 𝑢 u ,再选择参数 𝑘 k ,分解为
𝑢 = 2 𝑘 𝑎 + 𝑏 , 0 ≤ 𝑏 < 2 𝑘 . u = 2 k a + b , 0 ≤ b < 2 k .
用 𝑎 a 个 0 后接一个 1 表示商,再用 𝑘 k bit 表示余数,就是一种 Rice code 的写法。比如 𝑒 = − 2 e = − 2 对应 𝑢 = 3 u = 3 ;取 𝑘 = 1 k = 1 ,商为 1、余数为 1,输出 01 加 1,共 3 bit。𝑘 k 太小会使大 residual 的 unary 部分很长,太大又浪费小 residual 的余数位,因此 FLAC 可以按 partition 选择参数,并发送选择结果 (van Beurden et al., 2024 ) 。
有损压缩:先改变坐标,再分配误差
仅靠无损建模通常不够。若允许重建值 ˆ 𝑥 x ^ 与原值 𝑥 x 略有不同,encoder 还要决定哪些误差值得保留。问题不只是“少留几位小数”:直接对每个 sample 一视同仁,未必能把误差放在合适的地方。
为什么先换坐标
考虑两个很接近的像素 [ 1 0 0 , 1 0 2 ] [ 100 , 102 ] 。分别描述它们会重复表示共同的亮度;更有用的两个量是“共同部分”和“差异”:
𝑐 0 = 𝑥 0 + 𝑥 1 √ 2 , 𝑐 1 = 𝑥 0 − 𝑥 1 √ 2 . c 0 = x 0 + x 1 2 , c 1 = x 0 − x 1 2 .
现在 𝑐 0 = 1 0 1 √ 2 c 0 = 101 2 ,𝑐 1 = − √ 2 c 1 = − 2 。两个数仍完整保留输入,但若预算紧张,把很小的差异量化成零,就会重建为 [ 1 0 1 , 1 0 1 ] [ 101 , 101 ] :共同亮度保住了,只损失局部变化。将归一化后的和与差作为坐标,正是最简单的正交变换。
一般写成 𝐜 = 𝐴 𝐱 c = A x ,其中 𝐴 ⊤ 𝐴 = 𝐼 A ⊤ A = I ,逆变换为 ˆ 𝐱 = 𝐴 ⊤ ˆ 𝐜 x ^ = A ⊤ c ^ 。于是
‖ 𝐱 − ˆ 𝐱 ‖ 2 2 = ‖ 𝐜 − ˆ 𝐜 ‖ 2 2 . ‖ x − x ^ ‖ 2 2 = ‖ c − c ^ ‖ 2 2 .
这说明正交变换不凭空缩小平方误差,而是给出一套可以分别控制的误差方向。对经常一起升降的 samples,换到这些方向后,系数的方差会变得很不均匀;此时才有理由不再平均分配 bits (Girod, 2012e ) 。
KLT 为什么选择 covariance 的特征向量,DCT 又解决了什么工程问题 假设向量已减去均值,covariance 为 Σ 𝑥 Σ x 。变换后的 covariance 是 𝐴 Σ 𝑥 𝐴 ⊤ A Σ x A ⊤ 。我们希望不同坐标不再有线性相关性,使逐个量化、逐个建模少遗漏一些结构;因此希望这个矩阵变成对角矩阵。对称矩阵可分解为 Σ 𝑥 = 𝑈 Λ 𝑈 ⊤ Σ x = U Λ U ⊤ ,选择 𝐴 = 𝑈 ⊤ A = U ⊤ 就实现了这一点。这就是 Karhunen–Loève transform(KLT),与 PCA 使用相同的主轴。
例如
Σ 𝑥 = 𝜎 2 [ 1 𝜌 𝜌 1 ] Σ x = σ 2 [ 1 ρ ρ 1 ]
的主轴就是上面的和与差,两个系数方差分别是 𝜎 2 ( 1 + 𝜌 ) σ 2 ( 1 + ρ ) 和 𝜎 2 ( 1 − 𝜌 ) σ 2 ( 1 − ρ ) 。取 𝜌 = 0 . 9 ρ = 0.9 ,得到 1 . 9 𝜎 2 1.9 σ 2 与 0 . 1 𝜎 2 0.1 σ 2 :差异坐标便宜的原因来自相邻 samples 的统计相关性。
KLT 的去相关不一般等于独立;对联合 Gaussian 向量,去相关还保证独立。其最优 coding gain 结论也依赖平方误差、高码率量化与合适 bit allocation 等模型,不能解释成它对任何实际 codec 都最优。更直接的工程障碍是 basis 随数据统计变化,可能需要传矩阵,而且一般没有简单的快速实现。
DCT 固定一组 cosine basis,能用快速、可分离的运算实现;对常见的平滑相关信号,它又能取得不错的能量集中效果。与把 block 两端直接接起来的周期 DFT 相比,DCT 对应的偶对称延拓也减少了端点跳变。这些性质让它成为成本与压缩效果之间的实用选择。
量化把哪些值视为“同一个”
一个标量 quantizer 把一段系数值映射到同一个整数 index,decoder 再把 index 还原为一个代表值。最简单的等间距设计先选 quantization step Δ 𝑘 Δ k :
𝑞 𝑘 = r o u n d ( 𝑐 𝑘 Δ 𝑘 ) , ˆ 𝑐 𝑘 = 𝑞 𝑘 Δ 𝑘 . q k = round ( c k Δ k ) , c ^ k = q k Δ k .
较大的 Δ 𝑘 Δ k 让更多小 coefficients 变成零,也让留下来的值更粗糙。Decoder 只能得到 ˆ 𝑐 𝑘 c ^ k ,不能找回 rounding 前的 𝑐 𝑘 c k ;这是典型有损 codec 的主要不可逆边界。
例如 𝑐 = 7 . 3 c = 7.3 时,Δ = 3 Δ = 3 重建为 6,Δ = 4 Δ = 4 却重建为更接近原值的 8。单个值的误差不一定随步长单调变化,但对平滑分布和足够细的量化区间,误差可近似看成在 [ − Δ / 2 , Δ / 2 ] [ − Δ / 2 , Δ / 2 ] 均匀分布。于是
𝔼 [ 𝑒 2 𝑞 ] ≈ 1 Δ ∫ Δ / 2 − Δ / 2 𝑒 2 d 𝑒 = Δ 2 1 2 . E [ e q 2 ] ≈ 1 Δ ∫ − Δ / 2 Δ / 2 e 2 d e = Δ 2 12 .
在固定范围内多给 1 bit,可把步长减半,噪声功率约降为四分之一,即约 6 dB。这里需要高分辨率、无 clipping 等条件;低幅纯音、很粗的量化或强烈非均匀分布不一定满足这个噪声近似 (Girod, 2012e ) 。
非均匀量化、Lloyd–Max 与 vector quantization 等间距未必适合固定数量的代表值。若大多数输入挤在零附近,就可以把更多代表值放在那里。怎样寻找位置?先固定代表值 𝑎 𝑗 a j ,每个输入应分给平方误差最小的代表值,所以相邻区间边界在两代表值的中点;再固定区间 𝐵 𝑗 B j ,最小化区间内平均平方误差,代表值就应是条件均值:
𝑎 𝑗 = 𝔼 [ 𝑋 ∣ 𝑋 ∈ 𝐵 𝑗 ] . a j = E [ X ∣ X ∈ B j ] .
交替更新边界和均值得到 Lloyd–Max iteration,通常收敛到局部最优。比如训练 samples 是 [ 0 , 1 , 2 , 9 , 1 0 ] [ 0 , 1 , 2 , 9 , 10 ] ,只允许两个代表值,分成前 3 个和后 2 个后,代表值为 1 与 9.5,边界为 5.25;各点仍属于原分组,这已经是一个稳定解。
如果 index 还要经过 entropy coding,“最近”就不一定是“最划算”。固定当前码长估计 ℓ 𝑗 ℓ j 后,应比较
𝑗 ∗ ( 𝑥 ) = a r g m i n 𝑗 [ ( 𝑥 − 𝑎 𝑗 ) 2 + 𝜆 ℓ 𝑗 ] . j ∗ ( x ) = arg min j [ ( x − a j ) 2 + λ ℓ j ] .
这会给短码代表值更大的吸引范围。常见的 dead-zone quantizer 把零附近的区间做宽,正是在用更多零换较低的码率;它与普通 round quantizer 中宽度为 Δ Δ 的零区间有所区别。
把标量 𝑥 , 𝑎 𝑗 x , a j 换成向量,就得到 vector quantization(VQ):整个小向量选一个 codeword,发送其 index。它可以利用标量量化遗漏的联合结构,但码本大小、搜索成本、训练数据和 decoder 共享码本都要算进代价。后面的神经音频 codebook 使用的也是这类操作。
把变换和量化接起来,就可以从两个 samples 扩展到一个图像块。对一个 𝑁 × 𝑁 N × N 、已减去中心值的图像 block 𝑓 ( 𝑥 , 𝑦 ) f ( x , y ) ,二维 DCT 可以写成
𝐶 ( 𝑢 , 𝑣 ) = 𝛼 ( 𝑢 ) 𝛼 ( 𝑣 ) 𝑁 − 1 ∑ 𝑥 = 0 𝑁 − 1 ∑ 𝑦 = 0 𝑓 ( 𝑥 , 𝑦 ) c o s ( 2 𝑥 + 1 ) 𝑢 𝜋 2 𝑁 c o s ( 2 𝑦 + 1 ) 𝑣 𝜋 2 𝑁 . C ( u , v ) = α ( u ) α ( v ) ∑ x = 0 N − 1 ∑ y = 0 N − 1 f ( x , y ) cos ( 2 x + 1 ) u π 2 N cos ( 2 y + 1 ) v π 2 N .
这里 𝛼 ( 0 ) = 1 / √ 𝑁 α ( 0 ) = 1 / N ,𝛼 ( 𝑘 ) = √ 2 / 𝑁 α ( k ) = 2 / N (𝑘 > 0 k > 0 )。因此 𝐶 ( 0 , 0 ) C ( 0 , 0 ) 是 block 平均值的 𝑁 N 倍;𝑢 u 或 𝑣 v 越大,basis 在空间中变化越快。二维 DCT 可以先对各行做一维 DCT,再对各列做一次。下面使用同一份 4 × 4 4 × 4 数值实际计算 DCT、逐频率量化与 inverse DCT。变换前后始终是 16 个数,量化后才出现大量零和不可逆误差。
一个真实计算的微型例子。DCT 集中能量但不减少数量;frequency-dependent quantization 产生零和不可逆误差,后续扫描与 entropy coding 才能用短 bitstream 表示这些零。
有限的 bits 应该先给谁
假设一块数据有两种编码:方案 A 用 20 bit,平方误差为 12;方案 B 用 28 bit,误差为 8。升级多花 8 bit,只降低 4 单位误差。如果另一块的同样 8 bit 能降低 10 单位误差,预算有限时应优先升级后一块。也就是说,要比较的是每增加一个 bit 能减少多少失真 。
把总码率约束 𝑅 ≤ 𝑅 0 R ≤ R 0 写成 Lagrangian,就得到 encoder 常用的 rate–distortion cost:
𝐽 ( 𝑚 ) = 𝐷 ( 𝑥 , ˆ 𝑥 𝑚 ) + 𝜆 𝑅 ( 𝑚 ) . J ( m ) = D ( x , x ^ m ) + λ R ( m ) .
𝑅 R 包含量化 coefficients、预测模式、模型参数等所有要发送的 bits;𝐷 D 衡量重建损失;𝜆 λ 是每个额外 bit 的失真代价。上述升级只有在 4 > 8 𝜆 4 > 8 λ 时才值得。增大 𝜆 λ 会更偏向省 bits;它对应光滑率失真曲线上 − d 𝐷 / d 𝑅 − d D / d R 的大小。实际候选是离散的,而且参考依赖会耦合多个 block,因而局部搜索不保证全局最优。
若暂时把各 transform coefficient 视为独立 Gaussian,方差为 𝜎 2 𝑘 σ k 2 ,要求平方误差 0 < 𝑑 𝑘 ≤ 𝜎 2 𝑘 0 < d k ≤ σ k 2 ,理论上达到该误差的最小码率是 𝑟 𝑘 = 1 2 l o g 2 ( 𝜎 2 𝑘 / 𝑑 𝑘 ) r k = 1 2 log 2 ( σ k 2 / d k ) 。对所有仍分到 bits 的系数,若某个系数多用一点码率能比另一个更有效地降误差,就应把预算移过去;平衡时,各系数的边际收益相同。这个 Gaussian 模型下,它意味着把误差均衡到某个水平 𝜃 θ :
𝑑 𝑘 = m i n ( 𝜎 2 𝑘 , 𝜃 ) , 𝑟 𝑘 = m a x ( 0 , 1 2 l o g 2 𝜎 2 𝑘 𝜃 ) . d k = min ( σ k 2 , θ ) , r k = max ( 0 , 1 2 log 2 σ k 2 θ ) .
若某个零均值系数本来的方差已低于 𝜃 θ ,直接重建为零就够了,无须给它“负数 bits”。这就是 reverse water-filling 的含义 (Girod, 2012f ) 。例如方差为 [ 1 6 , 4 , 1 ] [ 16 , 4 , 1 ] ,取 𝜃 = 1 θ = 1 ,最优理论分配是 [ 2 , 1 , 0 ] [ 2 , 1 , 0 ] bit/coefficient,误差为 [ 1 , 1 , 1 ] [ 1 , 1 , 1 ] 。这些是对长序列的平均码率,不是在要求一个单独系数拥有分数长度的固定码字。
这也解释了为什么“所有频率保留相同精度”不一定有效。真实媒体不严格是 Gaussian,人的感知也不等于 MSE;把误差改成带权重的 ∑ 𝑘 𝑤 𝑘 𝑑 𝑘 ∑ k w k d k ,就应平衡加权 的边际收益。后面色度降采样与音频 masking,都会改变哪些误差更值得避免。
理论的 R(D) 与实际 encoder 的 D + λR 有什么区别 前者问所有可能的编码方法能达到什么极限,后者是在一组可实现方案中做选择。对 memoryless source 和逐 sample 累加的 distortion,允许平均误差不超过 𝐷 0 D 0 时,理论极限可写成
𝑅 ( 𝐷 0 ) = m i n 𝑝 ( ˆ 𝑥 ∣ 𝑥 ) : 𝔼 [ 𝑑 ( 𝑋 , ˆ 𝑋 ) ] ≤ 𝐷 0 𝐼 ( 𝑋 ; ˆ 𝑋 ) . R ( D 0 ) = min p ( x ^ ∣ x ) : E [ d ( X , X ^ ) ] ≤ D 0 I ( X ; X ^ ) .
Mutual information 𝐼 ( 𝑋 ; ˆ 𝑋 ) I ( X ; X ^ ) 衡量重建中仍保留了多少关于原信号的信息;离散情形可写成 𝐻 ( 𝑋 ) − 𝐻 ( 𝑋 ∣ ˆ 𝑋 ) H ( X ) − H ( X ∣ X ^ ) 。允许更大误差,就能让更多不同输入共享同一类重建,所需信息减少。这个渐近极限容许很长的 block,不替实际系统解决有限延迟、搜索或码表开销。
对方差为 𝜎 2 σ 2 的 memoryless Gaussian source 和 MSE,若 0 < 𝐷 0 < 𝜎 2 0 < D 0 < σ 2 ,有
𝑅 ( 𝐷 0 ) = 1 2 l o g 2 𝜎 2 𝐷 0 . R ( D 0 ) = 1 2 log 2 σ 2 D 0 .
可以从“原信号减去尚未确定的误差”理解这个式子:Gaussian 的 differential entropy 为 1 2 l o g 2 ( 2 𝜋 𝑒 𝜎 2 ) 1 2 log 2 ( 2 π e σ 2 ) ,方差不超过 𝐷 0 D 0 的误差最多有 1 2 l o g 2 ( 2 𝜋 𝑒 𝐷 0 ) 1 2 log 2 ( 2 π e D 0 ) 的 entropy,相减给出下界;选择与重建独立的 Gaussian 误差可以达到它。若 𝐷 0 ≥ 𝜎 2 D 0 ≥ σ 2 ,恒定输出均值就够了,码率为零。它给出每增加 1 bit、误差降为四分之一的理想规律,并不保证现实图片增加 1 bpp 就一定提升 6 dB。
图像:在二维空间里分离结构与颜色
RGB 便于显示,却不总适合按视觉重要性分配 bits。照片和视频 codec 常把颜色变换为亮度样分量 𝑌 Y 与两个色度分量 𝐶 𝑏 , 𝐶 𝑟 C b , C r 。颜色变换本身不减少 sample 数;chroma subsampling 才会减少。
对一个 2 × 2 2 × 2 区域,RGB 或 YCbCr 4:4:4 都有 12 个 samples。YCbCr 4:2:0 保留 4 个 𝑌 Y ,让四个位置共享 1 个 𝐶 𝑏 C b 与 1 个 𝐶 𝑟 C r ,一共 6 个 samples。
同一个 2 × 2 2 × 2 区域:YCbCr 只是重排颜色信息;4:2:0 才把 12 个 samples 减到 6 个。图中共享关系是采样结构示意,不规定具体的 chroma siting 或上采样 filter。
人类视觉通常对高频亮度变化比高频色度变化敏感,所以照片常能承受色度降采样;文字、UI、像素画、彩色细线和继续编辑的素材则可能出现明显 color bleeding。实际降采样前需要 low-pass filtering,避免细密的颜色变化折叠成错误的低频图案;随后丢掉的色度细节无法从少量 samples 唯一恢复。4:2:0 是有损操作;从 RGB 换到 YCbCr、却仍保留 4:4:4,不能单凭名称断言有损。
JPEG 怎样把一块系数真正写成 bits
前面的 DCT 例子已经把平滑结构集中到少数系数。Baseline JPEG 把这条思路落实到每个 8 × 8 8 × 8 block:对 8-bit samples 先减去 128,再做 DCT,最后用 quantization table 为不同频率选择步长 (Joint Photographic Experts Group, n.d. ) 。低频通常量化得细一些,高频通常粗一些;这不是一条“超过某频率就删除”的硬边界,而是对不同 basis 所产生误差的不同定价。
量化之后仍有 64 个整数,文件怎样变小?先看 DC。邻近 block 的平均亮度往往相近,因此 JPEG 对同一 component 的量化 DC 做差分,只发送它相对前一个 DC 的变化。其余 63 个 AC 则沿 zigzag 顺序展开,使通常更稀疏的高频部分排在后面,便于描述连续的零。Zigzag 本身是可逆排列;它只有和后面的 run-length coding 配合才节省 bits。
假设前一块的量化 DC 是 10,当前块按 zigzag 排列为
[ 1 2 ⏟ D C , − 3 , 0 , 0 , 2 , − 1 , 0 , … , 0 ] . [ 12 ⏟ DC , − 3 , 0 , 0 , 2 , − 1 , 0 , … , 0 ] .
DC 只需编码差值 1 2 − 1 0 = 2 12 − 10 = 2 。AC 不逐个发送零,而是先发送“下一个非零数前有几个零”,再说明这个非零数的大小。JPEG 用 SIZE category 表示附加值需要多少 bits:对非零整数 𝑣 v ,𝑠 = ⌊ l o g 2 | 𝑣 | ⌋ + 1 s = ⌊ log 2 | v | ⌋ + 1 。例如 category 2 覆盖 − 3 , − 2 , 2 , 3 − 3 , − 2 , 2 , 3 ,还需 2 bits 才能区分具体值。于是本例变成:
要表示的内容 送入 Huffman coder 的符号 随后附加的值 bits DC difference 为 2 2 DC category 2 2 10第一个 AC 为 − 3 − 3 ( R U N , S I Z E ) = ( 0 , 2 ) ( RUN , SIZE ) = ( 0 , 2 ) 00两个零之后出现 2 2 ( 2 , 2 ) ( 2 , 2 ) 10紧接着出现 − 1 − 1 ( 0 , 1 ) ( 0 , 1 ) 0剩余 AC 全是零 EOB,即 ( 0 , 0 ) ( 0 , 0 ) 无
表中的 (RUN, SIZE) 是一个联合符号,Huffman table 决定它的码字;附加 bits 再确定符号与精确幅值,并不是直接把这两个十进制数字原样存入文件。这里 category 2 的 00,01,10,11 分别表示 − 3 , − 2 , 2 , 3 − 3 , − 2 , 2 , 3 ,负数也不是二进制补码。若非零值前超过 15 个零,可用特殊 ZRL 符号反复表示每组 16 个零。Decoder 读完这些符号,就能恢复 64 个量化整数 ,随后反量化和 inverse DCT;熵编码并没有再增加损失 (Girod, 2012b ) 。
这条链也解释了常见伪影。相邻 block 各自量化,边界两侧误差不连续会产生 blocking;锐利边缘所需的一组高频系数被粗化,会出现 ringing;缓慢变化的区域若只有少数可用重建值,则会出现 banding。所谓“压缩痕迹”不是一个现象,必须沿 decoder 反查是哪一步制造的。
从独立小块到跨尺度的 wavelet
Block DCT 把每个小块分别处理,误差容易暴露人为边界。一个自然的问题是:能否让 basis 跨越邻域,同时仍只保留与原图一样多的 coefficients?Subband coding 用一组 analysis filters 分离不同频带,再对每个分支降采样;配对的 synthesis filters 把它们合回去。只要满足 perfect reconstruction 条件,未量化时所有分支合起来就能恢复输入 (Girod, 2012c ) 。
先用最小的 Haar 例子理解“分离后还能合回去”。相邻两个数 𝑢 , 𝑣 u , v 通常相近,我们可以分别记录它们的平均和偏离平均的量:
𝑎 = 𝑢 + 𝑣 2 , 𝑑 = 𝑢 − 𝑣 2 . a = u + v 2 , d = u − v 2 .
Decoder 用 𝑢 = 𝑎 + 𝑑 , 𝑣 = 𝑎 − 𝑑 u = a + d , v = a − d 精确恢复。𝑎 a 是低频分支,𝑑 d 是细节分支;两个输入变成一个平均、一个差值,数量并没有减少。这里为方便手算采用未归一化形式;正交归一化的 Haar 则把两个分母都改成 √ 2 2 ,并相应调整逆变换。
对一行 [ 1 0 , 1 2 , 1 4 , 1 6 ] [ 10 , 12 , 14 , 16 ] ,第一层得到平均 [ 1 1 , 1 5 ] [ 11 , 15 ] 和细节 [ − 1 , − 1 ] [ − 1 , − 1 ] 。平均本身还相关,可以再拆一次,得到整体平均 1 3 13 与较粗尺度细节 − 2 − 2 。最终保存的是
[ 1 3 ⏟ 最粗平均 , − 2 ⏟ 较粗细节 , − 1 , − 1 ⏟ 较细细节 ] . [ 13 ⏟ 最粗平均 , − 2 ⏟ 较粗细节 , − 1 , − 1 ⏟ 较细细节 ] .
仍然是 4 个数。若保留全部,逐层逆变换恢复原序列;若只把较细的两个 − 1 − 1 量化为零,重建变成 [ 1 1 , 1 1 , 1 5 , 1 5 ] [ 11 , 11 , 15 , 15 ] ;若连 − 2 − 2 也丢掉,才变成 [ 1 3 , 1 3 , 1 3 , 1 3 ] [ 13 , 13 , 13 , 13 ] 。降采样不必然有损:两条互补分支一起保留时,可以只是可逆换坐标;只保留低频分支,才失去细节。 这也说明它和前面的 chroma subsampling 不同,后者没有另外发送被去掉的高频色度。
二维图像先沿行、再沿列做同样的分离,得到 𝐿 𝐿 , 𝐿 𝐻 , 𝐻 𝐿 , 𝐻 𝐻 L L , L H , H L , H H 四个子带。这里第一个字母表示水平方向滤波,第二个表示垂直方向:𝐿 𝐿 L L 是缩小的平滑结构,𝐻 𝐿 H L 保留沿水平方向变化的细节,𝐿 𝐻 L H 保留沿垂直方向变化的细节,𝐻 𝐻 H H 保留两个方向都快速变化的细节。继续分解 𝐿 𝐿 L L ,就得到从大轮廓到细纹理的多尺度表示。
Haar 的短滤波器适合手算;更长的 wavelet filters 可以跨越更多像素,减少独立小块的边界感。每个降采样分支单独看可能带有 aliasing,分析与合成滤波器必须成对设计,让这些项在重建时抵消;不能任意选两个 low/high-pass filters 就假定它们可逆。代价是滤波支撑、边界处理和实现复杂度,粗量化也仍可能产生模糊与 ringing。
为什么整数 wavelet 里的 rounding 仍然可以可逆? 只把平均值四舍五入会丢信息,但 lifting 可以让每一步 rounding 都有可重算的输入。先用偶数位置预测奇数位置,保存预测误差,再利用误差更新偶数位置;decoder 按相反顺序撤销更新和预测。
以最简单的一对整数为例,令
𝑑 = 𝑣 − 𝑢 , 𝑎 = 𝑢 + ⌊ 𝑑 2 ⌋ . d = v − u , a = u + ⌊ d 2 ⌋ .
给定 ( 𝑎 , 𝑑 ) ( a , d ) ,decoder 先算 𝑢 = 𝑎 − ⌊ 𝑑 / 2 ⌋ u = a − ⌊ d / 2 ⌋ ,再算 𝑣 = 𝑢 + 𝑑 v = u + d 。例如 ( 𝑢 , 𝑣 ) = ( 3 , 6 ) ( u , v ) = ( 3 , 6 ) 变成 ( 𝑎 , 𝑑 ) = ( 4 , 3 ) ( a , d ) = ( 4 , 3 ) ,逆向仍得到 ( 3 , 6 ) ( 3 , 6 ) 。Rounding 的结果可以从已知 𝑑 d 重新算出,所以没有把两个不同输入合并成同一表示。JPEG 2000 的 reversible 5/3 transform 使用类似的整数 lifting 结构,只是预测与更新会结合邻居;若颜色变换也可逆、不做有损量化并发送全部必要 bitplanes,就能无损重建。它的另一条常用路径是 irreversible 9/7 transform (Girod, 2012c ) 。
JPEG 2000:先收到的 bits 应该先改善画面
有了多尺度系数,下一个问题是怎样组织文件,才能让接收端逐步获得更清楚的图像。把每个系数都完整发完再发下一个,可能只让一个角落很精确,而其余位置仍然未知。Bitplane coding 改成先处理所有系数的高位,再逐层补低位。
例如量化系数的绝对值 1 3 = ( 1 1 0 1 ) 2 13 = ( 1101 ) 2 。扫描 2 3 2 3 对应的 bitplane 时,它首次显著:decoder 知道幅值至少为 8,同时收到正负号;下一层得知幅值至少为 12;再下一层把范围缩小到 [ 1 2 , 1 4 ) [ 12 , 14 ) ,最后一层确定为 13。此前一直不显著的系数,只需继续说明它是否越过当前阈值。邻近系数是否已经显著能预测当前 bit 的概率,因此这些二进制决定再交给 context-adaptive arithmetic coding,而不是不加区分地逐 bit 原样存储 (Girod, 2012c ) 。
JPEG 2000 把各 subband 再划分为可以独立熵编码的 code-blocks 。这些 code-blocks 是 wavelet 变换后的编码单元,不等同于 JPEG 在像素上分别做 DCT 的小块。每个 code-block 产生可逐步细化的码流;encoder 比较多发一段带来的失真下降 − Δ 𝐷 − Δ D 和额外码长 Δ 𝑅 Δ R ,优先保留 − Δ 𝐷 / Δ 𝑅 − Δ D / Δ R 较大的合法增量,选择各块的截断点。这就是 EBCOT 的核心思路 (Taubman, 2000 ) :先生成带有多个截断点的块码流,再按总预算分配它们的长度。
一个 bitplane 还可以分成三次扫描:先处理靠近已显著系数、较可能刚变显著的位置,再细化此前已经显著的系数,最后清理剩余位置。这样的 significance propagation、magnitude refinement 和 cleanup passes 使概率模型更有针对性,也提供比“整层保留或整层舍弃”更细的截断选择。
这里仍是前面的 𝐷 + 𝜆 𝑅 D + λ R :如果追加一段使 Δ 𝐷 + 𝜆 Δ 𝑅 < 0 Δ D + λ Δ R < 0 ,这段信息就值得发送。实际必须尊重每块码流的先后依赖,不能从中间任意挑 bits。不同块的增量再组织成 quality layers;resolution progression 则优先传输较粗尺度所需的信息。这使“先有粗略全图,再逐渐补质量或分辨率”成为 bitstream 本身的性质。低码率下可以提前停止;满足可逆条件并保留全部信息时,则能一路细化到无损。换来的成本是更复杂的编码、上下文建模和码流组织,并不意味着对任何图像和运行环境都必然更合适。
Wavelet coefficients 之间的关系还能怎样节省 bits? 同一位置、同一方向的粗尺度细节,与更细尺度的对应系数存在关联。EZW 用一棵跨尺度的树组织它们:在当前阈值下,如果一个系数和全部后代都不显著,就用一个 zerotree 符号描述整棵树;若某个后代显著,则继续展开。阈值不断减半,已显著系数补精度,新的显著系数逐步出现 (Shapiro, 1993 ) 。它利用的是“许多小系数在空间和尺度上聚集”的结构,不能仅凭父系数小就擅自省略后代。JPEG 2000 的 EBCOT 采用独立 code-block 内的上下文编码,并不直接使用这套跨子带的 zerotree 语法。
现代图像格式仍在回答同一组问题:
格式 主要机制 有损能力 常见考虑场景 PNG scanline prediction + DEFLATE 无 UI、截图、线稿、需逐 sample 保留 JPEG block DCT + quantization + entropy coding 有,标准另有少用模式 兼容性优先的照片交付 JPEG 2000 wavelet + embedded bitplane coding 有 / 无 多分辨率、大图与渐进传输 WebP VP8 intra transform;另有独立 lossless mode 有 / 无 Web 照片、透明图与动画 AVIF HEIF 中的 AV1 image coding 有 / 无 高效率照片、HDR/WCG、现代终端 JPEG XL VarDCT 或 Modular 有 / 无 HDR、渐进解码、专业或受控生态
WebP lossy 使用 VP8 的 intra prediction 与 transform coding,lossless mode 则采用另一套可逆变换和概率编码 (Google for Developers, n.d. ) 。AVIF 可表达多种 bit depth、SDR/HDR、wide color gamut 与 image sequence (Alliance for Open Media, n.d. ) 。JPEG XL 同时设计了 VarDCT 与 Modular 路径,并支持 progressive decoding、alpha 和 legacy JPEG 的 bit-exact reconstruction (Joint Photographic Experts Group, 2023 ) 。
音频:变换之外,还要与时间赛跑
一段 PCM 音频是按固定 sample rate 取得的振幅序列。无损音频可以预测相邻 samples,再精确编码残差;有损音频还要决定:哪些误差可以共存于同一时刻,哪些误差必须避开安静的频段和瞬间? 这个问题同时约束了变换、量化和播放延迟。
为什么音频不能直接对整段做一次频率变换
整首歌的完整 Fourier transform 保留幅度与相位,因此可以逆变换,时间信息并没有消失。问题是每个 basis 横跨整首歌:修改一个系数,影响可能遍及整段;实时通话也不能等说完一句话才输出第一个 sample。我们需要让系数对应有限的时间区域,才能随声音的变化调整误差。
把第 𝑚 m 个重叠 frame 写成
𝑋 𝑚 , 𝑘 = ∑ 𝑛 𝑥 [ 𝑛 + 𝑚 𝐻 ] 𝑤 [ 𝑛 ] 𝜙 𝑘 [ 𝑛 ] , X m , k = ∑ n x [ n + m H ] w [ n ] ϕ k [ n ] ,
其中 𝑤 [ 𝑛 ] w [ n ] 是 window,𝐻 H 是 frame 步长,𝜙 𝑘 [ 𝑛 ] ϕ k [ n ] 是第 𝑘 k 个 frequency basis。只观察长度为 𝑇 T 的信号,典型的频率区分尺度约为 1 / 𝑇 1 / T :在 48 kHz 下,960 个 samples 是 20 ms,对应约 50 Hz;240 个 samples 是 5 ms,对应约 200 Hz。两个频率相差 50 Hz 的音调,在 20 ms 内积累一个周期的相对相位变化,在 5 ms 内只积累四分之一个周期,因此短窗口更难分开它们。具体可分辨程度还取决于 window、幅度和噪声,并不等于仅看 DFT 的 bin 间距。
硬切 frame 会让截断边缘参与频谱分析;平滑 window 可以减轻 spectral leakage。可是把每一帧两端都压低又会丢失边界附近的信号,于是相邻帧 overlap,由相邻窗口共同覆盖这些位置。MDCT 进一步解决了“重叠部分是否需要编码两次”的问题:长度 2 𝑁 2 N 的窗口每次前进 𝑁 N 个 samples,只输出 𝑁 N 个系数;单帧逆变换会包含 time-domain aliasing,但相邻帧以匹配的窗口 overlap-add 后,这些项相互抵消。未量化、边界处理正确时,整体可以完美重建 (Aalto University, n.d. ) 。
为什么分析和合成窗口的平方和等于 1? 先只看同一个 sample 在两帧中的直接贡献。若分析、合成都乘同一个窗口,第一帧给它权重 𝑤 [ 𝑛 ] 2 w [ n ] 2 ,第二帧给它权重 𝑤 [ 𝑛 + 𝑁 ] 2 w [ n + N ] 2 。想让原有振幅不变,就需要
𝑤 [ 𝑛 ] 2 + 𝑤 [ 𝑛 + 𝑁 ] 2 = 1 , 0 ≤ 𝑛 < 𝑁 . w [ n ] 2 + w [ n + N ] 2 = 1 , 0 ≤ n < N .
这称为 Princen–Bradley condition。一个满足它的选择是长度 2 𝑁 2 N 的对称 sine window:
𝑤 [ 𝑛 ] = s i n ( 𝜋 ( 𝑛 + 1 / 2 ) 2 𝑁 ) , 0 ≤ 𝑛 < 2 𝑁 . w [ n ] = sin ( π ( n + 1 / 2 ) 2 N ) , 0 ≤ n < 2 N .
两项的角度相差 𝜋 / 2 π / 2 ,平方相加就是 s i n 2 𝜃 + c o s 2 𝜃 = 1 sin 2 θ + cos 2 θ = 1 。它解释了重叠相加为什么不会平白放大或缩小信号;完整 MDCT 的重建还依赖 basis 的对称结构来抵消 aliasing,不能只给任意变换配上这个窗口就宣称可逆 (Aalto University, n.d.b ) 。
长窗口还有另一笔代价。设前 15 ms 很安静,第 16 ms 出现鼓点;若整个窗口共享较粗的频域量化,逆变换后的误差会覆盖窗口内的其他时刻,于是鼓点之前也可能出现沙沙声,这就是 pre-echo 。鼓点后的误差和鼓点前的误差,并不具有相同的可听性。遇到这种 transient,切换为短窗口可以缩短误差扩散的时间范围;代价是频率分辨率降低、参数更频繁。CELT 的短块机制正是为限制这类失真服务 (Montgomery, 2010 ) 。
Psychoacoustics 不是简单删除“听不见的频率”
先考虑一个实验:播放固定频率的弱 tone,逐渐增加它周围的带通噪声宽度,同时保持噪声的单位带宽功率不变。起初噪声越宽,tone 越难听见;继续加宽后,阈值增长趋缓。这提示我们,检测这个 tone 时,听觉并没有把所有频率的噪声等权相加,而主要整合某个邻近频带内的干扰。Critical band 描述的就是这种频率选择性;它不是把频谱机械切成等宽方格,其绝对带宽通常随中心频率增大 (Oxenham, 2005 ) 。
因此,一个误差能否被察觉,不只取决于它自身有多大,还取决于附近有什么声音。已有声音使目标的检测阈值升高,称为 masking 。同样能量的窄带 tone 和 noise 也不一定产生相同的 masking:频谱是否集中、时间包络是否起伏,都可能改变可听性。Perceptual encoder 据此估计各频带允许的噪声,再决定量化精度;MPEG 的典型模型会区分 tonal 与 noise-like maskers,形成总 masking threshold,最后映射到编码频带的预算 (Lewiston, 2005 ) 。
把这个过程变成可计算的账本。对某一帧的频带 𝑏 b ,记原信号能量为 𝑆 𝑏 S b ,模型允许的量化噪声能量为 𝑀 𝑏 M b ,实际量化噪声能量为 𝑁 𝑏 N b 。它们必须在一致的频带、时间范围和归一化方式下比较。目标 𝑁 𝑏 ≤ 𝑀 𝑏 N b ≤ M b 可以改写成两个更直观的比值:
S M R 𝑏 = 1 0 l o g 1 0 𝑆 𝑏 𝑀 𝑏 , S N R 𝑏 = 1 0 l o g 1 0 𝑆 𝑏 𝑁 𝑏 . SMR b = 10 log 10 S b M b , SNR b = 10 log 10 S b N b .
SMR 是 signal-to-mask ratio,表示需要把误差压到信号下方多少 dB;SNR 表示量化器实际做到了多少。两者相减,信号项消去:
N M R 𝑏 = 1 0 l o g 1 0 𝑁 𝑏 𝑀 𝑏 = S M R 𝑏 − S N R 𝑏 . NMR b = 10 log 10 N b M b = SMR b − SNR b .
因此 NMR 不大于 0 dB,才表示误差位于该模型预测的 阈值之下。一个频带即使声音很响,只要 masking 也很强,就未必最需要 bits;相反,一个不那么响、却很少受到 masking 的 tone 可能需要更精确的编码。
下面构造一个只用于说明分配逻辑的例子。三个频带系数数量相同,signal level 与 masking level 采用同一能量参考。简化量化器在每系数使用 𝑞 q bits 时达到 S N R ≈ 6 𝑞 SNR ≈ 6 q dB,忽略真实量化器的常数项、entropy coding 和参数开销。
频带 Signal level Masking level 所需 SMR 初始 𝑞 q 初始 NMR A 60 dB 42 dB 18 dB 4 − 6 − 6 dBB 45 dB 15 dB 30 dB 4 + 6 + 6 dBC 30 dB 18 dB 12 dB 2 0 0 dB
总预算对应 𝑞 𝐴 + 𝑞 𝐵 + 𝑞 𝐶 = 1 0 q A + q B + q C = 10 。初始分配 ( 4 , 4 , 2 ) ( 4 , 4 , 2 ) 让 A 比需要的精度多出 6 dB,B 却超阈值 6 dB;把 A 的每系数 1 bit 移给 B,得到 ( 3 , 5 , 2 ) ( 3 , 5 , 2 ) ,三带都恰好达到 0 dB NMR,总 bits 没有增加。这是一个非常小的例子,却已经说明了为什么“按振幅分 bits”和“按可听误差分 bits”不等价。
前面推导的每 bit 约 6 dB 这里只用于简化估算;真实 encoder 必须用实际的量化结果和码长重新检查。频带宽度不同意味着多给“每系数 1 bit”的成本也不同。若预算不足以让所有 NMR 都低于零,就要比较每多花一 bit 能减少多少可听失真,回到前面的 rate–distortion 取舍。
Masking threshold 也不是永远有效的硬边界:它随时间、声压、听者和播放环境改变。只看频谱能量的模型还会遗漏包络、fine structure 和听觉非线性,因此阈值内的误差不能自动等同于每个人都听不见 (Oxenham, 2005 ) 。Watery/metallic texture、瞬态 smear、pre-echo 和 stereo image collapse 对应不同失真,不能都归因于高频被删掉。
保住每个频带的能量,再描述它的形状
若码率很低,逐个系数量化可能把一个本来密集的频带变成少数几个非零尖峰。即使整体误差能量尚可,声音也可能从连续的噪声质感变成不自然的 tone。CELT 把频带的整体能量与带内形状分开编码,先保护较粗的 spectral envelope,再用剩余 bits 描述细节 (Montgomery, 2010 ) 。
要做到这一点,只需先问一个几何问题:怎样改变向量方向,却不连带改变长度?对非零频带向量 𝐗 𝑏 X b ,先计算
𝐸 𝑏 = ‖ 𝐗 𝑏 ‖ 2 2 , 𝐮 𝑏 = 𝐗 𝑏 √ 𝐸 𝑏 , ‖ 𝐮 𝑏 ‖ 2 = 1 . E b = ‖ X b ‖ 2 2 , u b = X b E b , ‖ u b ‖ 2 = 1.
分别编码 𝐸 𝑏 E b 和单位向量 𝐮 𝑏 u b ,decoder 再做 ˆ 𝐗 𝑏 = √ ˆ 𝐸 𝑏 ˆ 𝐮 𝑏 X ^ b = E ^ b u ^ b 。只要 shape 的码字也归一化到单位长度,改变 shape 就不会进一步改变已经重建的带能量。
例如 𝐗 = ( 3 , 4 ) X = ( 3 , 4 ) 的能量为 25。假设粗量化后只能选择方向 ( 1 , 1 ) ( 1 , 1 ) ,先归一化再乘回 5,得到 ˆ 𝐗 = ( 5 / √ 2 , 5 / √ 2 ) X ^ = ( 5 / 2 , 5 / 2 ) ,能量仍为 25;直接逐项量化成 ( 4 , 4 ) ( 4 , 4 ) 则变成 32。两者都改变了频谱,但前一种表示把“多少能量”和“能量怎样分布”变成两项可分别控制的误差。
Opus 的 CELT shape coding 使用 pyramid vector quantization(PVQ) :用满足 ∑ 𝑖 | 𝑣 𝑖 | = 𝐾 ∑ i | v i | = K 的整数向量描述方向,再归一化;𝐾 K 越大,可选择的方向越密,所需 bits 通常越多。能量本身仍然经过量化,所以保持的是解码出的能量 ,不是原信号能量的无误差副本 (Valin et al., 2012 ) 。
Stereo 则利用声道之间的相关性。Mid/side 变换
𝑀 = 𝐿 + 𝑅 2 , 𝑆 = 𝐿 − 𝑅 M = L + R 2 , S = L − R
在保留精度时可逆;因为 𝐿 = 𝑀 + 𝑆 / 2 L = M + S / 2 、𝑅 = 𝑀 − 𝑆 / 2 R = M − S / 2 ,当左右相近时,编码较小的 𝑆 S 往往比重复编码两份相似信号划算。若进一步只发送某些频段的能量和方向线索,让 decoder 合成左右声道,就进入 intensity stereo 等有损建模:声场细节也成为码率分配的一部分。
Speech 与一般音频需要不同的先验
元音中既有相邻 samples 的相关性,也有跨一个 pitch 周期的重复;嘴形和声道共振又决定了缓慢变化的谱包络。于是可以先用短时预测解释包络,再用长时预测解释残差的周期性,把还解释不了的部分交给 excitation 编码。这就是 source–filter 思路如何与前面的预测压缩连接起来 (Valin, 2007 ) 。
先让过去的 𝑝 p 个 samples 预测当前值,保留下来的差额为
𝑒 [ 𝑛 ] = 𝑥 [ 𝑛 ] − 𝑝 ∑ 𝑖 = 1 𝑎 𝑖 𝑥 [ 𝑛 − 𝑖 ] . e [ n ] = x [ n ] − ∑ i = 1 p a i x [ n − i ] .
若这组 𝑎 𝑖 a i 在一小段内相对稳定,就只需每段发送参数,decoder 逐 sample 做 ˆ 𝑥 [ 𝑛 ] = ∑ 𝑖 ˆ 𝑎 𝑖 ˆ 𝑥 [ 𝑛 − 𝑖 ] + ˆ 𝑒 [ 𝑛 ] x ^ [ n ] = ∑ i a ^ i x ^ [ n − i ] + e ^ [ n ] 。前一个式子描述理想的 source–filter 分解;实际有损编码必须用量化后的参数和重建历史评估 excitation,才能与 decoder 的状态一致。对于有明显周期的 excitation,还可以预测 ˆ 𝑒 [ 𝑛 − 𝑇 ] e ^ [ n − T ] ,编码 ˆ 𝑒 [ 𝑛 ] = 𝛽 ˆ 𝑒 [ 𝑛 − 𝑇 ] + 𝑐 [ 𝑛 ] e ^ [ n ] = β e ^ [ n − T ] + c [ n ] ;𝑇 T 表示 pitch period,𝑐 [ 𝑛 ] c [ n ] 是新的 innovation。以 16 kHz、200 Hz 的理想周期信号为例,𝑇 = 1 6 0 0 0 / 2 0 0 = 8 0 T = 16000 / 200 = 80 samples:短时预测利用紧邻的样本,pitch prediction 则借用 80 个 samples 以前的激励。
CELP 把可用的 innovation 序列组织成 codebook,让 encoder 尝试候选、通过本地 decoder 合成声音,再比较 perceptually weighted error;最后发送索引与参数。需要比较的是合成后的误差,因为同样大小的 excitation 误差通过不同共振滤波器后,可能被放大得很不一样。这种 analysis-by-synthesis 把 encoder 的搜索成本换成了 decoder 的紧凑表示 (Valin, 2007 ) 。音乐里的多声部、打击乐和噪声往往不满足单一 voice 模型,因此一般音频仍需要更灵活的 transform 路线。
Opus 把这两类结构放在同一个格式内:SILK 面向预测编码,CELT 面向低延迟变换编码;hybrid mode 由 SILK 处理低频、CELT 处理高频。CELT-only 支持 2.5–20 ms 的 frame,并有 2.5 ms 的变换 look-ahead;它们只是 codec delay 的组成部分,网络传输、jitter buffer 和设备缓冲还要另外计入 (Valin et al., 2012 ) 。
缩短 frame 也会抬高每秒的固定开销。假设每包只有一帧,包头固定 40 bytes:20 ms 一包时每秒 50 包,包头占 4 0 × 8 × 5 0 = 1 6 40 × 8 × 50 = 16 kbit/s;5 ms 一包则每秒 200 包,达到 64 kbit/s。这是只考虑固定包头的示意算例,实际协议封装不同,但关系始终成立:降低等待时间,往往需要支付更多传输开销,并牺牲一部分跨时间分析和预测的机会。
Codec 主要思路 更值得注意的约束 FLAC LPC/fixed prediction + Rice-coded residual 无损、解码简单、残差必须精确恢复 MP3 hybrid filter bank + perceptual quantization 时频分辨率、masking 模型与旧工具设计 AAC MDCT 路线 + perceptual/stereo tools 瞬态、频带预算、profile 与 container Opus SILK + CELT,可适应 speech 与 music 低延迟、包开销、packet loss 与预测状态
MP3 的 polyphase filter bank 与 MDCT hybrid 结构见 MPEG 概述 (Moving Picture Experts Group, n.d. ) ;AAC 的 transform 与 perceptual tools 见其技术说明 (Moving Picture Experts Group, n.d.a ) 。这些名称代表不同的设计取舍,比较时仍应回到具体码率、输入内容和延迟约束。
视频:在空间预测之外,再借用已重建的时间
固定相机拍摄菜单时,墙和菜单几乎不动,只有价格牌从左边移到右边。把每一帧独立压成图片会重复描述背景。最简单的改进,是没变化的区域沿用上一帧,只更新变化的区域;但只要价格牌移动,旧位置和新位置都会产生差值。进一步利用「它只是搬了家」,才能把这两大片差值变成一个位移和少量 residual。这也解释了为什么视频从 interframe prediction 走向 motion compensation (Girod, 2012g ) 。
对当前块 𝑥 𝑡 x t 和参考重建帧 ˆ 𝑥 𝑟 x ^ r ,若 encoder 选择位移 𝑣 = ( 𝑣 𝑥 , 𝑣 𝑦 ) v = ( v x , v y ) ,prediction 可以写成
𝑝 𝑡 ( 𝑖 , 𝑗 ) = ˆ 𝑥 𝑟 ( 𝑖 + 𝑣 𝑦 , 𝑗 + 𝑣 𝑥 ) , 𝑒 𝑡 = 𝑥 𝑡 − 𝑝 𝑡 . p t ( i , j ) = x ^ r ( i + v y , j + v x ) , e t = x t − p t .
这里 𝑣 v 指向参考帧中拿来预测的位置,方向不一定与物体移动方向相同。Motion vector 也不是物体真实运动或 dense optical flow;它只是使编码更便宜的一个位移假设。被价格牌挡住的背景、新出现的文字、光照变化都无法仅靠平移恢复,仍要交给 residual 或 intra prediction。
示例只处理一块亮度值。预测已经解释了大部分平缓背景,残差主要留下中央变化;DCT 把这种相关图样集中到较少频率,量化再把小系数变成零。最后的系数由左侧同一组数值现场计算,并非手填结果。
怎样找到值得发送的 motion vector
先固定一个块,枚举参考帧中允许的位置。可以把每个候选的 sample 差取绝对值后求和,得到 SAD,也可以用平方和 SSD。对一个 1 6 × 1 6 16 × 16 块,若横纵各搜索 − 1 6 − 16 到 1 6 16 ,穷举要比较 3 3 2 = 1 0 8 9 33 2 = 1089 个位置,约计算 2 7 . 9 27.9 万次 sample 差;整帧、多参考帧和多种块大小会继续放大工作量。
因此 encoder 会先试邻块预测出的 vector,或在低分辨率图上粗搜,再到原分辨率细化。还有一种不损失当前搜索目标最优解的加速:累加 SAD 时,一旦部分和已经超过现有最佳候选,就停止计算,因为余下的绝对差不可能把它减小。限定搜索位置、提前接受「足够好」的候选则可能漏掉更好结果;这些取舍解释了同一 codec 的快慢 preset 为什么可以产生不同体积 (Wiegand & Girod, 2012 ) 。
仅使 SAD 最小仍然不够:相邻块都向右移动时,发送「与邻块相同」通常比发送一个独立 vector 便宜。实用搜索常先比较 prediction error 与 vector bits 的近似成本,再对入围候选执行变换、量化和重建,用完整的 𝐷 + 𝜆 𝑅 D + λ R 决定结果。这里前一阶段的 prediction error 与最后重建后的 distortion 是两种不同的量。
一个大块若同时盖住静止墙面和移动价格牌,一条 vector 无法同时对齐两者。分成小块可以降低 residual,却要发送更多分块、模式和 motion 信息。下面是假设某一区域完成实际编码后得到的示意账本 ;𝐷 D 是该区域重建的平方误差总和,𝑅 R 包含全部语法和 residual bits,并非真实 codec 的测量结果。
候选 𝐷 D 𝑅 R 𝐷 + 2 𝑅 D + 2 R 一个大块共用一条 vector 240 24 288 分为四块,分别选择 vector 100 60 220 继续细分,拟合每处变化 70 100 270
在 𝜆 = 2 λ = 2 时,中间方案胜出;如果 bits 更贵,改用 𝜆 = 5 λ = 5 ,三个成本分别成为 3 6 0 , 4 0 0 , 5 7 0 360 , 400 , 570 ,大块反而更合适。分块不是越细越好,预测器也不是越复杂越好;它们都要用 residual 的节省偿还描述自身的成本。
物体也不会只移动整数个像素。若边缘实际移动了半个 sample,只查整数位置会留下正负相邻的边缘残差。Fractional-pel prediction 先按规定的 interpolation filter 计算参考网格之间的值,再搜索 half-pel、quarter-pel 等位置;decoder 用相同滤波规则重建预测,无须收到一张真的高分辨率参考图。
为什么细小的位移误差也会留下明显 residual? 设一维参考信号与当前信号本可通过平移对齐,但位移估计还差 𝛿 δ 。忽略遮挡,未对齐部分为 𝑠 ( 𝑢 ) − 𝑠 ( 𝑢 − 𝛿 ) s ( u ) − s ( u − δ ) ;把局部信号近似成直线,有
𝑠 ( 𝑢 ) − 𝑠 ( 𝑢 − 𝛿 ) ≈ 𝛿 𝑠 ′ ( 𝑢 ) . s ( u ) − s ( u − δ ) ≈ δ s ′ ( u ) .
因此同样的半像素误差,在平坦墙面几乎没有影响,在文字边缘却很明显。若再把参考噪声或不能由运动解释的变化记为 𝑛 ( 𝑢 ) n ( u ) ,则 residual 近似为 𝛿 𝑠 ′ ( 𝑢 ) + 𝑛 ( 𝑢 ) δ s ′ ( u ) + n ( u ) 。提高运动精度只能减少前一项;噪声与遮挡开始占主导后,继续细化 vector 的收益会变小。这是 motion-compensated coding 的误差分析所揭示的限制 (Girod, 2012h ) 。
多个参考也可提供互补证据:把两份已对齐预测做加权组合,可能抵消部分噪声或补足单帧看不清的结构,但共同存在的错误不会凭空消失,reference index、额外 vector,以及需要发送的权重也要计入成本。
为什么 encoder 必须在内部解码一遍
假设某个 sample 这一帧与上一帧都是 1 0 0 100 ,但上一帧在 decoder 中已重建为 9 8 98 。若 encoder 对原始值作差,会发送 1 0 0 − 1 0 0 = 0 100 − 100 = 0 ,decoder 加回后仍是 9 8 98 ;若 encoder 也从 9 8 98 预测,就知道当前 residual 应为 2 2 。两端要从同一个已知状态出发 ,否则 residual 修正的根本不是同一个 prediction。
把 residual 重建误差记为 𝑞 𝑡 q t ,即 ˆ 𝑒 𝑡 = 𝑒 𝑡 + 𝑞 𝑡 e ^ t = e t + q t 。在加回 prediction、尚未执行后续滤波或 clipping 的简单模型里,只要两端采用同一个 𝑝 𝑡 p t ,就有
ˆ 𝑥 𝑡 = 𝑝 𝑡 + ˆ 𝑒 𝑡 = 𝑝 𝑡 + ( 𝑥 𝑡 − 𝑝 𝑡 ) + 𝑞 𝑡 = 𝑥 𝑡 + 𝑞 𝑡 . x ^ t = p t + e ^ t = p t + ( x t − p t ) + q t = x t + q t .
过去的重建误差已经进入当前 residual,因而不会再额外叠加一份未知的 predictor mismatch。这正是闭环 DPCM 的作用 (Girod, 2012i ) 。它不表示参考质量不重要:差的参考会使 residual 更难压缩;若发生丢包,两端参考不同,上面的抵消也不成立。
Encoder 因此包含一条本地 decoder:反量化、逆变换、加回 prediction、执行同样的 in-loop filters,再把重建帧 放入 reference buffer。
上路把 residual 变成 bitstream;下路在 encoder 内部执行 decoder 的重建步骤。预测器把同一个 prediction 同时送到减法与加法节点,滤波后的重建帧才进入 reference buffer。图中省略色度路径、多个参考帧和具体滤波阶段。
Reference 依赖怎样影响播放与随机访问
用一段简化的 𝐼 0 , 𝐵 1 , 𝐵 2 , 𝑃 3 I 0 , B 1 , B 2 , P 3 来看依赖。𝐼 0 I 0 使用帧内信息,𝑃 3 P 3 可从 𝐼 0 I 0 预测;若两个 B picture 同时借用 𝐼 0 I 0 和 𝑃 3 P 3 ,则必须先解码 𝐼 0 , 𝑃 3 I 0 , P 3 ,再解码 𝐵 1 , 𝐵 2 B 1 , B 2 ,最后按时间顺序显示。所谓「未来参考」是显示时间上的未来,在使用它时已经完成解码。
一种示意性 GOP:箭头从参考帧指向使用它预测的帧。B₁、B₂ 必须等 P₃ 先解码,B₄ 必须等 P₅,因此解码顺序不同于显示顺序。实际 codec 可采用更深的层级 B、不同参考集合或低延迟结构;图中关系不代表唯一配置。
双参考有机会改善预测,却也需要等待、重排和 buffer。实时通话常选择只依赖已到达画面的结构;离线分发更容易承受 lookahead。I、P、B 描述的是预测方式,不是画质等级,而且现代标准的参考列表比上述例子更灵活:B picture 不一定同时引用时间上的前后两帧,也可以成为后续 picture 的参考。
围绕 intra picture 组织的一组画面通常称为 Group of Pictures(GOP);具体参考关系可以封闭在组内,也可以跨组。随机访问还需要切断旧依赖。单张 intra picture 能独立重建,并不自动保证它之后的图片不再引用更早内容;H.264 的 IDR 则提供明确的解码刷新边界 (Wiegand et al., 2003 ) 。把独立访问点隔得更远通常能少付几次完整画面的成本,也会拉长 seek 时需要补解码的距离,并扩大参考损坏可能影响的范围。
预测与滤波还可以利用哪些结构
运动只能消除一部分冗余。同一帧里,文字边缘常同时出现在 luma 与 chroma 中,即使转换到 𝑌 ′ 𝐶 𝑏 𝐶 𝑟 Y ′ C b C r 后,这种局部关系也不一定消失。AV1 的 Chroma from Luma(CfL) 先取得已重建、且与 chroma 网格对齐的 luma 𝐿 L ,减掉块均值 ¯ 𝐿 L ¯ ,保留明暗变化;再给这份变化乘上颜色通道自己的比例,最后加上由邻块得到的平均颜色预测:
𝑝 𝐶 ( 𝑖 , 𝑗 ) = 𝐶 D C + 𝛼 𝐶 ( 𝐿 ( 𝑖 , 𝑗 ) − ¯ 𝐿 ) . p C ( i , j ) = C DC + α C ( L ( i , j ) − L ¯ ) .
𝐶 C 分别取 𝐶 𝑏 C b 、𝐶 𝑟 C r 。这样既复用了边缘,又把颜色的平均值和变化幅度分开控制。Encoder 发送所选 𝛼 𝐶 α C 和剩余 residual;decoder 不必猜颜色,也不必重新拟合参数。是否采用 CfL,仍由包含参数 bits 的率失真成本决定 (Trudeau et al., 2018 ) 。Xiph 的局部颜色演示说明了为什么这种简单模型在小块上比在整张图上更合理 (Montgomery, 2018 ) 。
量化后,块边界可能不连续,锐边附近还可能出现 ringing。直接对所有方向模糊会连真实边缘一起抹掉。AV1 的 CDEF 先从重建块估计主方向,再沿该方向及较弱的辅助方向滤波;相邻 sample 与中心差得过大时,constraint 会压低甚至排除其贡献,减少跨越真实边缘的混合 (Midtskogen & Valin, 2017 ) 。
这类 in-loop filter 同时影响当前画面和后续参考;放到播放器末尾的独立美化滤镜则只影响显示。两者位置不同,不能互相替换。Xiph 的 CDEF 演示也把 deblocking、CDEF、loop restoration 放回了这条重建路径中 (Montgomery, 2018b ) 。
从相邻帧到相邻视点:立体视频为什么还需要 depth? 左右相机看到的是同一场景的不同投影。可以先编码一个视点,再用它预测另一个视点;这次补偿的是 disparity,参考关系从时间方向扩展到了视点方向。对已经校正、光轴平行的双相机,设焦距为 𝑓 f 、相机间距为 𝑏 b ,某点相对左相机的横向位置为 𝑋 X 、深度为 𝑍 Z 。两幅图中该点的投影横坐标分别是 𝑓 𝑋 / 𝑍 f X / Z 与 𝑓 ( 𝑋 − 𝑏 ) / 𝑍 f ( X − b ) / Z ,相减得到
𝑑 = 𝑓 𝑏 𝑍 . d = f b Z .
这里若 𝑓 f 用像素为单位,𝑑 d 也用像素为单位。近处点移动得更多,因此全图用一个平移量无法同时对齐前景和背景。有了 texture 与 depth,就能把像素投影到中间视点,用较少真实视点合成更多观看位置;但遮挡后新露出的区域仍需要其他视点或额外信息。
Depth 的失真也应按它的用途计算:深度边缘偏移会把前景颜色投到背景中,即使 depth MSE 不大,合成画面仍可能明显破损。因此 multiview-plus-depth coding 会利用深度图的平滑区域与清晰边界,并在模式选择时考察合成视点的失真 ,不只考察深度数值本身 (Wiegand, 2012 ) 。这又回到了同一个问题:被压缩的数据服务于什么重建目标,𝐷 D 就应该衡量什么。
H.264/AVC 奠定了现代 block-based hybrid codec 的经典轮廓,包括可变块运动补偿、多参考帧、整数变换、in-loop deblocking 与上下文熵编码 (Wiegand et al., 2003 ) 。后续标准继续扩大合法预测、分块、变换和滤波的候选空间:
AV2 1.0.0 规范于 2026 年 5 月发布;规范完成只说明 decoder 规则已经固定,不表示终端、编码器和内容生态已经成熟。任何「新 codec 固定节省 30%」的说法都应追问 encoder 版本、preset、内容、分辨率、bit depth、GOP、延迟与质量指标。
同一个率失真公式,三种不同的“看起来一样”
文件小不等于 codec 好:把信息全部丢掉会得到最小文件。公平比较要在多个 rate 点编码同一组有代表性的内容,画 rate–distortion curve,并固定 encoder、版本、preset、采样格式、metadata 与 decoder 对齐方式。
图像常用 bits per pixel(bpp),音频和视频常用 bits per second;它们的分母不同,不能直接拿数值比较。MSE 与 PSNR 提供可重复的 sample-domain 基线:
M S E = 1 𝑛 ∑ 𝑖 ( 𝑥 𝑖 − ˆ 𝑥 𝑖 ) 2 , P S N R = 1 0 l o g 1 0 𝐿 2 M S E . MSE = 1 n ∑ i ( x i − x ^ i ) 2 , PSNR = 10 log 10 L 2 MSE .
这里 𝑛 n 是参与比较的 sample 数,𝐿 L 是该表示的峰值,例如 8-bit unsigned 图像取 255、归一化到 [ 0 , 1 ] [ 0 , 1 ] 时取 1;两端必须使用相同的数值范围。
但相同 MSE 可以分布在完全不同的位置。图像还要检查文字、暗部、肤色、锐边和 banding;视频要加入 motion、flicker、scene cut 与时序稳定性,VMAF 等模型指标只能作为一种视角 (Netflix, n.d. ) ;音频尤其不能只看 waveform MSE,因为很小的时间偏移就会造成巨大 sample error,却可能听起来一样,反过来也可能出现 MSE 不大但很刺耳的结构化噪声。
高质量音频的小失真可按 ITU-R BS.1116 组织严格 listening test (International Telecommunication Union, 2015 ) ;中等质量 codec 常用带隐藏参考和 anchor 的 MUSHRA 方法 (International Telecommunication Union, 2015b ) 。这揭示了一个通用原则:perceptual metric 不是 encoder 的装饰,它定义了“允许把误差搬到哪里”。 若目标改成人脸识别、ASR 或机器视觉,合适的 distortion 还会再次改变。
Rate control 则在更长时间尺度分配预算。图片通常面对单文件大小;音乐可用 VBR 让复杂片段多花 bits;实时语音还受 frame size、jitter buffer 与 packet loss 约束;视频点播可两遍分析并建立 adaptive bitrate ladder,直播则要服从 VBV、网络吞吐与端到端延迟。相同平均 bitrate 不代表相同峰值、延迟或体验。
学习式 codec 学到的仍是同一份账本
学习式图像压缩常写成
𝑦 = 𝑔 𝑎 ( 𝑥 ) , ˆ 𝑦 = 𝑄 ( 𝑦 ) , ˆ 𝑥 = 𝑔 𝑠 ( ˆ 𝑦 ) , y = g a ( x ) , y ^ = Q ( y ) , x ^ = g s ( y ^ ) ,
并用 entropy model 估计
𝑅 ≈ − ∑ 𝑖 l o g 2 𝑝 ( ˆ 𝑦 𝑖 ∣ 已解码 c o n t e x t ) , L = 𝔼 [ 𝐷 ( 𝑥 , ˆ 𝑥 ) + 𝜆 𝑅 ] . R ≈ − ∑ i log 2 p ( y ^ i ∣ 已解码 context ) , L = E [ D ( x , x ^ ) + λ R ] .
这里沿用前文 𝐷 + 𝜆 𝑅 D + λ R 的约定;论文也常写成 𝑅 + 𝛽 𝐷 R + β D ,相应权重互为倒数,不能只看参数的数值大小。早期 end-to-end 工作已把 nonlinear transform、quantization approximation 与 entropy model 放进同一个训练目标 (Ballé et al., 2017 ) 。Analysis transform、probability model 与 synthesis transform 由数据学习,但 quantized representation、side information 和 decoder consistency 仍然存在。
从前面的推导看,网络各部分的分工很明确:analysis transform 学习比固定 DCT 更合适的坐标;量化限制 decoder 真正能收到的取值;entropy model 减少用错误分布编码时的 cross-entropy 成本。Scale hyperprior 再发送一组辅助 latent ˆ 𝑧 z ^ ,先解码它来估计主 latent 的分布 (Ballé et al., 2018 ) 。账本因此是
𝑅 ≈ − l o g 2 𝑝 ( ˆ 𝑧 ) − l o g 2 𝑝 ( ˆ 𝑦 ∣ ˆ 𝑧 ) , R ≈ − log 2 p ( z ^ ) − log 2 p ( y ^ ∣ z ^ ) ,
而不是只算第二项。若辅助信息花 100 bit,却只让主 latent 省 60 bit,就没有码率收益;若省 300 bit,净省才是 200 bit。这个判断与发送一个 motion vector 或一组 LPC coefficients 完全一致。JPEG AI 的 core coding system 已成为国际标准,目标同时包括人类观看与 compressed-domain machine tasks (Joint Photographic Experts Group, 2025 ) 。
音频模型可把 waveform 编成低帧率 latent,再用多级 vector quantization 分配离散码本;SoundStream 还把 reconstruction 与 adversarial/perceptual objectives 放进端到端训练 (Zeghidour et al., 2021 ) 。视频模型则让当前 latent 以已解码 temporal context 为条件;DCVC 把这种 context 放到 feature domain (Li et al., 2021 ) ,后续的 DCVC-RT 又把实时吞吐作为明确目标 (Jia et al., 2025 ) 。
有些以感知质量为目标的学习式 codec,会更主动地让 decoder 补出未逐 sample 编码的纹理或声音。前面的 CELP 和 intensity stereo 也会合成信号;这里改变的是生成模型的能力与训练目标,感知上合理 和忠实保留来源之间的取舍仍然存在。对娱乐内容,这可能在极低码率下更自然;对文字、医学影像、证据录音或机器测量,“听起来/看起来像”不能替代“事实相同”。所谓多模态语义压缩,必须先写清楚它承诺保留的是 waveform、像素、任务结果,还是人能辨认的语义。
由统一视角得到的几个判断
第一,压缩不是寻找一个神奇的缩小函数,而是设计 encoder 与 decoder 共享的语言。Prediction、transform 和 learned latent 都在让要发送的句子更短;bitstream 必须包含 decoder 无法自行推导的每一项选择。
第二,side information 不是额外负担的反例,而是一笔投资。Motion vector、LPC coefficients、scale factor、window type 和 hyperprior 都在付少量 bits,换更便宜的 residual;是否值得只由总账决定。
第三,图像、音频和视频的核心差别可以归结为三件事:可利用的坐标轴、容许误差的感知模型,以及 decoder 必须何时给出结果。音频和视频多出的时间轴不仅增加冗余,也带来 causality、latency、seek、packet loss 与状态同步。
第四,transform 不是自动压缩,而是在选择误差的形状。二维 DCT 让图像误差按空间频率分配;音频 filter bank/MDCT 让噪声按时间与频率分配;motion compensation 先把视频的时间变化对齐,再变换剩余误差。
最后,格式选择应从 decoder 端倒推:能否丢信息、内容是什么、谁来解码、允许多少延迟、是否需要随机访问、硬件是否支持、编码成本是否值得。格式名称和一个 quality=80 数字都无法替代这些约束。
值得继续读的课程、笔记与技术文章
正文把课程中与媒体压缩直接相关的内容串成了同一条设计路线。进一步阅读时,可以按下面的对应关系查找原讲义中的完整证明、图示和实验:
资料与版本 本文已经展开的内容 继续阅读的方向 Stanford EE398A,Winter 2011–2012 (Girod, 2012b ) Prefix/Huffman/Rice 与 arithmetic coding、条件熵、量化与 VQ、KLT/DCT、rate–distortion、subband/wavelet、JPEG/JPEG 2000、帧间与多视图预测 编码定理的完整证明、快速搜索与变换实现、课程习题 MIT HST.723,Spring 2005 的 perceptual audio 实验讲义 (Lewiston, 2005 ) 听觉频带与 masking、量化噪声、频带 bit allocation 和可听性判断 实際聆听 masking patterns,并测量不同频率、声级下的阈值 Xiph 工程演示 (Montgomery, n.d. ) 采样与 dither、低延迟音频建模、跨颜色预测与方向性滤波 对照可听、可视样例观察失真;具体解码过程再查 FLAC/Opus RFC 和视频规范
EE398A 的官网公开讲义对应上述 2012 年课程;MIT 此处引用的是 2005 年的专门音频编码实验材料。它们用于解释基础机制,现代 codec 的工具和 bitstream 规则则使用正文相应的标准与原始论文。课程目录中的具体文件也已在相关概念旁单独引用,便于直接跳到所需章节。
References
Aalto University. (n.d.a).
Modified Discrete Cosine Transform (MDCT) . Introduction to Speech Processing.
speechprocessingbook.aalto.fi
Aalto University. (n.d.b).
Windowing . Introduction to Speech Processing.
speechprocessingbook.aalto.fi
Alliance for Open Media. (2026).
AV2 Bitstream & Decoding Process Specification (Version 1.0.0).
av2.aomedia.org
Ballé, J., Laparra, V., & Simoncelli, E. P. (2017). End-to-End Optimized Image Compression.
International Conference on Learning Representations .
openreview.net
Ballé, J., Minnen, D., Singh, S., Hwang, S. J., & Johnston, N. (2018). Variational Image Compression with a Scale Hyperprior.
International Conference on Learning Representations .
openreview.net
Bross, B., Wang, Y.-K., Ye, Y., Liu, S., Chen, J., & Sullivan, G. J. (2021). Overview of the Versatile Video Coding (VVC) Standard and Its Applications.
IEEE Transactions on Circuits and Systems for Video Technology ,
31 (10), 3736–3764.
doi.org
Girod, B. (2012a).
Arithmetic Coding . Stanford University, EE398A, Winter 2011–2012, lecture 3.
web.stanford.edu
Girod, B. (2012b).
EE398A: Image and Video Compression . Stanford University, EE398A, Winter 2011–2012 course handouts.
web.stanford.edu
Girod, B. (2012c).
EE398A: JPEG Standard . Stanford University, Winter 2012 lecture slides.
web.stanford.edu
Girod, B. (2012d).
EE398A: JPEG-2000 . Stanford University, Winter 2012 lecture slides.
web.stanford.edu
Girod, B. (2012e).
EE398A: Subband and Wavelet Coding . Stanford University, Winter 2012 lecture slides.
web.stanford.edu
Girod, B. (2012f).
Entropy and Lossless Coding . Stanford University, EE398A, Winter 2011–2012, lecture 1.
web.stanford.edu
Girod, B. (2012g).
Exploiting Statistical Dependence for Compression . Stanford University, EE398A, Winter 2011–2012, lecture 2.
web.stanford.edu
Girod, B. (2012h).
Interframe Coding of Video Signals . Stanford EE398A Image and Video Compression, Winter 2011–2012 lecture slides.
web.stanford.edu
Girod, B. (2012i).
Motion-Compensated Hybrid Coding . Stanford EE398A Image and Video Compression, Winter 2011–2012 lecture slides.
web.stanford.edu
Girod, B. (2012j).
Predictive Coding . Stanford EE398A Image and Video Compression, Winter 2011–2012 lecture slides.
web.stanford.edu
Girod, B. (2012k).
Quantization . Stanford University, EE398A, Winter 2011–2012, lecture 5.
web.stanford.edu
Girod, B. (2012l).
Rate-Distortion Theory . Stanford University, EE398A, Winter 2011–2012, lecture 4.
web.stanford.edu
Girod, B. (2012m).
Transform Coding . Stanford University, EE398A, Winter 2011–2012, lecture 7.
web.stanford.edu
Google for Developers. (n.d.).
WebP Compression Techniques .
developers.google.com
Han, J., Li, B., Mukherjee, D., Chiang, C.-H., Grange, A., Chen, C., Su, H., Parker, S., Deng, S., Joshi, U., Chen, Y., Wang, Y., Wilkins, P., Xu, Y., & Bankoski, J. (2021). A Technical Overview of AV1.
Proceedings of the IEEE ,
109 (9), 1435–1462.
doi.org
International Telecommunication Union. (2015a).
Methods for the Subjective Assessment of Small Impairments in Audio Systems (ITU-R BS.1116-3).
itu.int
International Telecommunication Union. (2015b).
Method for the Subjective Assessment of Intermediate Quality Level of Audio Systems (ITU-R BS.1534-3).
itu.int
Jia, Z., Li, B., Li, J., Xie, W., Qi, L., Li, H., & Lu, Y. (2025). DCVC-RT: Towards Real-Time Deep Video Compression.
Proceedings of the IEEE/CVF Conference on Computer Vision and Pattern Recognition , 12543–12552.
openaccess.thecvf.com
Joint Photographic Experts Group. (2023).
JPEG XL White Paper .
ds.jpeg.org
Joint Photographic Experts Group. (2025).
JPEG AI Becomes an International Standard .
jpeg.org
Joint Photographic Experts Group. (n.d.).
JPEG 1 .
jpeg.org
Lewiston, C. (2005).
Fundamentals of Perceptual Audio Encoding . MIT HST.723 Neural Coding and Perception of Sound, Spring 2005, Lab II slides.
ocw.mit.edu
Li, J., Li, B., & Lu, Y. (2021). Deep Contextual Video Compression.
Advances in Neural Information Processing Systems ,
34 , 18114–18125.
papers.nips.cc
Midtskogen, S., & Valin, J.-M. (2017).
The AV1 Constrained Directional Enhancement Filter (CDEF) .
arxiv.org
Montgomery, C. (2010).
Next Generation Audio: CELT Update 20101223 . Xiph.Org technical demonstrations.
people.xiph.org
Montgomery, C. (2013).
Digital Show & Tell . Xiph.Org video presentation and accompanying transcript.
xiph.org
Montgomery, C. (2018a).
Next Generation Video: AV1, Part 1: Chroma from Luma . Xiph.Org demo pages.
people.xiph.org
Montgomery, C. (2018b).
AV1: Next Generation Video, Part 2: The Constrained Directional Enhancement Filter . Xiph.Org demo pages.
people.xiph.org
Montgomery, C. (n.d.).
Monty’s Demo Pages .
people.xiph.org
Moving Picture Experts Group. (n.d.a).
Advanced Audio Coding .
mpeg.chiariglione.org
Moving Picture Experts Group. (n.d.b).
MPEG-1 and MPEG-2 Audio .
mpeg.chiariglione.org
Mukherjee, D., Bankoski, J., Grange, A., Han, J., Koleszar, J., Wilkins, P., Xu, Y., & Bultje, R. S. (2013). The Latest Open-Source Video Codec VP9: An Overview and Preliminary Results.
2013 Picture Coding Symposium , 390–393.
doi.org
Netflix. (n.d.).
VMAF: Perceptual Video Quality Assessment Based on Multi-Method Fusion .
github.com
Oxenham, A. J. (2005).
Frequency Selectivity and Masking . MIT HST.723 Neural Coding and Perception of Sound, Spring 2005, Lecture 4.
ocw.mit.edu
Shapiro, J. M. (1993). Embedded Image Coding Using Zerotrees of Wavelet Coefficients.
IEEE Transactions on Signal Processing ,
41 (12), 3445–3462.
doi.org
Sullivan, G. J., Ohm, J.-R., Han, W.-J., & Wiegand, T. (2012). Overview of the High Efficiency Video Coding (HEVC) Standard.
IEEE Transactions on Circuits and Systems for Video Technology ,
22 (12), 1649–1668.
doi.org
Taubman, D. (2000). High Performance Scalable Image Compression with EBCOT.
IEEE Transactions on Image Processing ,
9 (7), 1158–1170.
doi.org
Trudeau, L. N., Egge, N. E., & Barr, D. (2018).
Predicting Chroma from Luma in AV1 .
arxiv.org
Valin, J.-M. (2007).
Introduction to CELP Coding . The Speex Codec Manual, Version 1.2 Beta 2, Chapter 7.
speex.org
Valin, J.-M., Vos, K., & Terriberry, T. B. (2012).
Definition of the Opus Audio Codec (Techreport RFC 6716). Internet Engineering Task Force.
doi.org
van Beurden, M., Coalson, J., & Weaver, A. (2024).
Free Lossless Audio Codec (FLAC) (Techreport RFC 9639). Internet Engineering Task Force.
doi.org
Wiegand, T. (2012).
3D Video Coding . Stanford EE398A Image and Video Compression, Winter 2011–2012 lecture slides.
web.stanford.edu
Wiegand, T., & Girod, B. (2012).
Motion Estimation for Video Coding . Stanford EE398A Image and Video Compression, Winter 2011–2012 lecture slides.
web.stanford.edu
Wiegand, T., Sullivan, G. J., Bjøntegaard, G., & Luthra, A. K. (2003). Overview of the H.264/AVC Video Coding Standard.
IEEE Transactions on Circuits and Systems for Video Technology ,
13 (7), 560–576.
doi.org
World Wide Web Consortium. (2025).
Portable Network Graphics (PNG) Specification (Third Edition) .
w3.org
Zeghidour, N., Luebs, A., Omran, A., Skoglund, J., & Tagliasacchi, M. (2021). SoundStream: An End-to-End Neural Audio Codec.
IEEE/ACM Transactions on Audio, Speech, and Language Processing ,
30 , 495–507.
doi.org