视频占互联网流量的八成,而它被压掉了 97% 以上。下面这三个开关就是压缩的三层,可以逐层剥掉——右边的码率柱子会跟着往上蹿,而左边的画面几乎看不出差别。这是一个真的编解码器:8×8 DCT、量化表、块匹配、熵编码,全部在你的浏览器里现算。
三个开关是压缩的三层,每一层都真的在跑:块匹配搜 ±8 像素、8×8 可分离 DCT、JPEG 亮度量化表、游程编码后按香农熵计比特(那是理想 Huffman/算术编码能达到的下界)。
右边柱子上的每个数都是这一段真编出来的,不是引用来的。⚠ 而这只是个玩具编解码器:真实的 H.264 还有亚像素运动补偿、帧内预测、可变块大小、CABAC,所以它能到 400 倍而这里只有几十倍。
① 我以为「三层加起来压缩比 100~400 倍」——默认设置实测只有 33.7 倍(把 q 拉到 16 才到 105 倍,代价是 PSNR 掉到 28.6 dB)。
② 我以为「运动补偿是最值钱的一层」——实测它只值 1.02 倍,几乎一分钱不值;最值钱的是熵编码(19.6 倍),其次是 DCT+量化(8.0 倍)。
③ 我以为「把输出再压一遍会变大」,第一版测出「还能压 6 倍」——那是我的测试写错了(用 LCG 造的假字节流,低位周期极短)。真做一遍见右边。
按上面那个「镜头在摇」按钮,运动补偿的价值会当场变化。实测四档:
静止 1.91 倍 → 整数摇镜(2 像素/帧)1.39 倍 → 非整数摇镜(1.6 像素/帧)1.01 倍。
病根是非整数平移:我的块匹配是整像素的,镜头每帧挪 1.6 个像素,它永远对不齐。这正是真实编码器要做 1/4 像素插值的全部原因——一个我原以为是细节的东西,是这一层能不能成立的前提。
把编出来的比特流(真实范围编码的输出)再喂给同一个熵编码器:只能再省 0.19%,而第二遍必须带的码表(256 个符号)就要多花 2304 比特 ⇒ 净结果比原来还大。
这是鸽巢原理的直接推论:不存在能压缩所有输入的压缩器。压缩靠的从来不是魔法,是真实数据有结构——而结构一旦被榨干,就再也榨不出东西了。