H.264 把自己分成两层:VCL 只管压得小,NAL 只管装得进——把【怎么压】和【怎么传】彻底拆开,这是它成为通用标准的关键设计。
9.1.2 讲了码流内部的分层,这一节讲H.264 整体上的两层划分,两者层次不同,别混淆。
一、两层各管一件事
H.264 的整个体系切成两块: VCL(视频编码层)——真正的压缩数据:片、宏块、残差;它只关心压得小不小; NAL(网络抽象层)——给 VCL 数据加一个头,把数据切成适合网络传输的单元;它只关心传得对不对。 所以【编码】与【传输】被彻底解耦,两边可以各自独立演进。
二、为什么要这么分
在 H.264 之前,视频编码标准是【面向具体网络】设计的: H.261 假设跑在 ISDN 上,H.263 假设跑在电路交换网或包网上; 网络一变,标准就得跟着打补丁; 而 H.264 的时代要同时面对 RTP、TS、MP4、文件、甚至不可靠的移动网络; 于是它干脆把【适配网络】这件事单独抽成一层——这就是 NAL 的由来。 一层不够用的地方,分两层往往是最省事的解法。
三、NAL 做了什么
NAL 的工作听起来很简单,但解决的都是真问题:
切片——把 VCL 数据切成一个个 NAL 单元,每个都带一个字节的头;
标识——头里的类型字段告诉接收方这一包是 SPS、PPS 还是片数据;
优先级——nal_ref_idc 字段标记重要性,网络拥塞时优先保它;
边界——加起始码或长度前缀,让接收方能切回原来的单元。
所以 NAL 层不碰任何压缩逻辑,它是纯粹的信封。
四、分层的代价
拆成两层不是没有成本,代价主要有两条: 多了一层头——每个 NAL 单元至少多 1 字节,对极小分辨率(比如低码率监控)来说占比不小; 错误处理变复杂——丢包时要判断【丢的是哪一类 NAL】,不同类型的丢失后果完全不同(丢 PPS 比丢一个片严重得多); 但从整体看,换来的通用性远远值得。 这也解释了为什么后来的 H.265 直接沿用了这套两层结构(第十一章)。
五、和 9.1.2 的区别
这里有一个很容易混淆的地方,专门澄清一句: VCL/NAL 是【系统级】的两层划分——一个管编码内容、一个管传输封装; 9.1.2 的五层是【码流内部】的层级划分——序列、图像、片、宏块、子块; 两者不在同一维度上:五层全部属于 VCL 的内容,而它们最终都会被装进一个个 NAL 单元往外传。 所以问题的正确提法是:这五层的元素被切分到哪些 NAL 单元里?
六、动手 Demo:VCL 与 NAL 两层
H.264 把自己的数据分成两个层面,各自解决一类问题。
rows = [("VCL", "视频编码层", "片、宏块的编码数据"),
("NAL", "网络抽象层", "给 VCL 数据加头,适配网络")]
for a, b, c in rows:
print("%-4s %-10s %s" % (a, b, c))
实跑输出:
--------------------------------------------------------------------
VCL 与 NAL 两层
--------------------------------------------------------------------
H.264 把自己的数据分成两个层面,各自解决一类问题。
层 全称 装什么
------------------------------------------------------------
VCL 视频编码层 片、宏块的编码数据(真正的压缩结果)
NAL 网络抽象层 给 VCL 数据加头,适配各种传输网络
这么分的理由只有一条:**把【怎么压】和【怎么传】拆开。**
**VCL 只管压得小,NAL 只管装得进——两边各自演进,互不影响。**
于是同一份 H.264 码流可以塞进 RTP、TS、MP4,甚至直接走文件。
这么分的理由只有一条:把【怎么压】和【怎么传】拆开。 VCL 只管压得小,NAL 只管装得进——两边各自演进、互不影响。
30 秒实验
- 把同一个视频分别封装成 MP4 与 TS,对比两者的文件大小。
- 差别主要来自封装开销——NAL 层的数据是一样的,信封换了而已。
常见误区
- 把 VCL/NAL 与五层结构当成一回事。它们分属系统级与码流内部两个维度。
- 以为 NAL 会参与压缩。它只是加头与切片,不碰任何编码逻辑。
- 以为两层结构是多余的。它正是 H.264 能同时服务文件与流媒体的原因。
自测三问(点开对答案)
1. VCL 与 NAL 分别负责什么? —— VCL 负责编码内容,NAL 负责加头与切片,适配网络传输。 2. 分成两层解决了什么问题? —— 把编码与传输解耦,让同一份码流能适配多种网络与封装。 3. NAL 头里的优先级字段有什么用? —— 标记该单元的重要性,网络拥塞时优先保障关键数据。- ☐ 下一节(9.1.4 档次与级别)
相关笔记
- H.264的NAL Unit — NAL 单元的字节格式
- H.264的句法元素 — 五层结构(别与这一节混淆)
- 数据封装和解封装 — 封装与编码的分工
- ITU/ISO/JVT — 标准为什么面向网络设计
- 🎬 FFmpeg入门详解 · 索引