帧内编码的流程是五步:切块、选预测模式、算残差、变换量化、熵编码——其中最花心思的是【选模式】,因为标准只给候选表,怎么选是编码器的自由。
8.3.4 把帧内与帧间摆在一起对照,这一节单独把帧内那一路走完。
一、五步流程
帧内编码一路走下来是这五步: 切块——把帧切成块(宏块或更小的块),逐块处理; 选预测模式——用已解码的相邻像素,试若干方向,选最像的那个; 算残差——实际像素减预测值,得到一个小得多的矩阵; 变换量化——对残差做变换、按 QP 量化,丢掉一部分; 熵编码——把模式、系数按概率写成短码。 注意第一步的关键词是【已解码】的相邻像素——与 8.2 的反馈支路是同一个道理:只能用解码端也拿得到的数据。
二、预测模式:标准给表,编码器选
这是帧内编码里最特殊的一处分工: 标准规定有哪些模式可选、每个模式的几何含义、模式号怎么写进码流; 标准不管怎么选——逐块试遍所有模式、算代价、取最小,是编码器自己的事。 所以【模式选择】是最能拉开编码器差距的地方之一:试得越细,压得越好,也越慢(与 8.2 的 preset 呼应)。
三、那个 1088 是怎么来的
讲流程绕不开一个问题:1080p 的 1080 不是 16 的整数倍。 1080 ÷ 16 = 67.5——除不尽; 但宏块必须整块整块地切,不能有半个宏块; 所以标准做法是按 1920×1088 编码,最后多出来的 8 行不显示。 于是 1920p 编码时一帧其实是 120×68 = 8160 个宏块。这个数字在很多资料里会被写成 1080/16 = 67,是错的。
四、帧内编码的代价
把流程走一遍,就能算出一帧的代价规模: 一张 1080p 帧 = 8160 个宏块,每个宏块都要走完五步; 30 帧/秒就是每秒 24.5 万个宏块; 而在帧内编码里,每个宏块都要试多个预测模式——乘起来就是编码器的负担。 所以硬件编码器把这一套做成固定流水线,软件编码器则靠 SIMD 与多线程硬扛。
五、帧内与帧间的流程对照
把两条流程并排放,差别只有一步: 帧内:选预测模式 → 算残差(预测在块内); 帧间:搜索参考块 → 算运动矢量 → 运动补偿 → 算残差(预测在帧间); 之后的变换、量化、熵编码三步完全共用。 所以整章的技术结构可以简化成一句话:预测那一步分家,后面三步合并。
六、动手 Demo:帧内编码的五步与宏块数量
帧内编码不参考别的帧,流程却是最标准的那一套。
w, h = 1920, 1088
mb = (w // 16) * (h // 16)
print("1920/16 = %d,1088/16 = %d" % (w // 16, h // 16))
print("一帧宏块数 = %d" % mb)
print("30 帧/秒 = 每秒 %d 个宏块" % (mb * 30))
实跑输出:
--------------------------------------------------------------------
帧内编码的五步与宏块数量
--------------------------------------------------------------------
帧内编码不参考别的帧,流程却是最标准的那一套。
切块 → 选预测模式 → 算残差 → 变换量化 → 熵编码
注意这里的 1088:**1920×1080 不是 16 的整数倍**——
1080 ÷ 16 = 67.5,所以标准做法是**按 1920×1088 编码,最后 8 行不显示**。
1920÷16 = 120,1088÷16 = 68,一帧共 **8160 个宏块**。
30 帧/秒就是 **每秒 244800 个宏块**要一个一个走完全套流程。
**这就是硬件编码器要专门做流水线的理由。**
注意这里的 1088:1920×1080 不是 16 的整数倍,1080 ÷ 16 = 67.5,所以按 1920×1088 编码,最后 8 行不显示。 一帧 8160 个宏块,30 帧/秒就是每秒 24.5 万个宏块要走完全套流程。
30 秒实验
- 拿一个 1080p 视频,手算它的宽有没有除尽 16(1920÷16、1080÷16)。
- 换一个 720p 的算(1280÷16、720÷16),看看哪种分辨率不需要补边。
常见误区
- 以为 1080 能整除 16。1080÷16 = 67.5,必须按 1088 编码。
- 以为预测模式由标准指定。标准只给候选表,怎么选是编码器的事。
- 以为帧内编码可以随便用原始像素预测。只能用已解码的相邻像素。
自测三问(点开对答案)
1. 帧内编码的五步是什么? —— 切块、选预测模式、算残差、变换量化、熵编码。 2. 1080p 为什么要按 1088 编码? —— 1080 不是 16 的整数倍,宏块必须整块切,多出的 8 行不显示。 3. 帧内与帧间的流程在哪一步分家? —— 预测那一步——之后变换、量化、熵编码完全共用。- ☐ 下一节(8.3.6 块与宏块)
相关笔记
- 块与宏块 — 处理单位长什么样
- 运动估计和运动补偿 — 帧间那一路的细节
- 帧内编码 — 四种预测方向的原理
- 变换 — 残差之后的第二步
- 🎬 FFmpeg入门详解 · 索引