# 视频打包 · 压缩帧怎么切成 RTP 包

> 一帧压缩视频可能几十 KB，而一个 RTP 包只能装一千多字节——得切。这一章讲清各编解码器专属的 RTP 打包格式（VP8/VP9/AV1/H264 各不同）、为什么打包要懂编解码器的内部结构、以及 marker 位如何标记一帧的结束。收尾发送侧。

- 作者：David（道雾轩）
- 专栏：音视频与 WebRTC 详解（https://daiw.org/manual/webrtc.md）
- 最后更新：2026-07-14
- 原文：https://daiw.org/manual/webrtc/video-packetization
- 转载与引用：请注明出处并附原文链接（https://daiw.org/about/copyright）

# 视频打包 · 压缩帧怎么切成 RTP 包

[编码器](https://daiw.org/manual/webrtc/video-encoder-abstraction)吐出一帧压缩数据（`EncodedImage`），可能几十甚至上百 KB。而一个 [RTP 包](https://daiw.org/manual/webrtc/rtp-packet)受 [MTU 限制](https://daiw.org/manual/webrtc/what-is-webrtc)只能装一千多字节。所以一帧要**切成多个 RTP 包**——这就是**打包（packetization）**。看似只是“切分”，却要懂编解码器的内部结构。收尾发送侧。

## 一帧 → 多包

<Callout type="info">
  **一帧压缩视频被切成多个 [RTP 包](https://daiw.org/manual/webrtc/rtp-packet)，它们共享同一个 [RTP 时间戳](https://daiw.org/manual/webrtc/rtp-packet)（都属于这一帧），[序号](https://daiw.org/manual/webrtc/rtp-packet)连续，最后一个包设 [marker 位](https://daiw.org/manual/webrtc/rtp-packet)标记“这帧到此为止”。** 接收端据此重组：看到一批相同时间戳的包，收集齐（靠序号连续、marker 收尾），就能[拼回完整的一帧](https://daiw.org/manual/webrtc/video-jitter-buffer)。这也回答了 [RTP 包那章](https://daiw.org/manual/webrtc/rtp-packet)关于 marker 位的伏笔——视频里它就是“帧结束”标记。一帧越大，切的包越多（[1080p 关键帧](https://daiw.org/manual/webrtc/video-decode-recovery)可能切几十上百个包），这也是为什么[大帧对丢包更脆弱](https://daiw.org/manual/webrtc/video-decode-recovery)：包越多，丢中一个的概率越大。
</Callout>

## 打包要懂编解码器

关键难点：**切分不能瞎切，要顺着编解码器的内部结构切。** 每种[编解码器](https://daiw.org/manual/webrtc/video-encoder-abstraction)的压缩数据有自己的组织方式，于是每种有**专属的 RTP 打包格式**（payload format）：

| 编解码器 | 打包格式 | 结构特点 |
| --- | --- | --- |
| VP8 | RFC 7741 | 分区（partition），便于[部分丢失恢复](https://daiw.org/manual/webrtc/fec) |
| VP9 | draft | 带 [SVC 层信息](https://daiw.org/manual/webrtc/simulcast-svc) |
| AV1 | RTP AV1 | OBU 单元，带 [SVC 结构](https://daiw.org/manual/webrtc/simulcast-svc) |
| H264/H265 | RFC 6184/RFC 7798 | NAL 单元（NALU） |

<Callout type="info">
  **为什么打包要懂编解码器结构？因为切分点和携带的元信息，直接影响丢包时能恢复多少。** 以 H264 为例，它的压缩数据由 **NAL 单元（NALU）** 组成（每个 NALU 是一个语义单元，如一个片 slice）。打包器会**尽量按 NALU 边界切**——这样丢一个包，受损的是完整的某个 NALU，而非“半个 NALU + 半个另一个”，[解码器](https://daiw.org/manual/webrtc/video-decode-recovery)更容易跳过 / 局部恢复。VP8 的分区、AV1 的 OBU 也是类似考量。此外，打包格式还携带**编解码器专属的元信息**——如 VP9/AV1 每个包属于哪个 [SVC 空间 / 时间层](https://daiw.org/manual/webrtc/simulcast-svc)，这样 [SFU](https://daiw.org/manual/webrtc/sframe) 不解码就能靠 RTP 层信息[丢弃高层](https://daiw.org/manual/webrtc/simulcast-svc)。**打包不是无脑切字节，而是“懂内容地切”**——这层编解码器专属逻辑，在 `modules/rtp_rtcp/source/` 的各个 `rtp_packetizer_xxx` 里。
</Callout>

## 与打包对应：接收侧解包

发送侧打包，接收侧就要**解包（depacketization）**——把一批 RTP 包还原成一帧压缩数据，交给[解码器](https://daiw.org/manual/webrtc/video-decode-recovery)。解包器（`rtp_depacketizer_xxx`）是打包器的逆，同样每种编解码器一个。它和[抖动缓冲](https://daiw.org/manual/webrtc/video-jitter-buffer)配合：抖动缓冲负责“等齐一帧的所有包、排好序”，解包器负责“把这些包的负载拼成一帧”。这是接收侧的第一步，下一章展开。

## 发送侧全景回顾

到这里，视频**发送侧**完整了。把[前几章](https://daiw.org/manual/webrtc/video-pipeline-overview)串起来：

```mermaid
flowchart LR
    CAM["采集(VideoFrame,I420)"] --> VSE["VideoStreamEncoder<br/>丢帧/缩放/自适应"]
    VSE --> ENC["VideoEncoder 编码<br/>(按分配的码率)"]
    ENC --> PACK["按编解码器打包 RTP<br/>(一帧多包,marker 收尾)"]
    PACK -->|"交给第 4-5 部分"| OUT["Pacing → SRTP → ICE"]
    ALLOC["码率分配(层/档)"] -.-> ENC
    ADAPT["自适应(分辨率/帧率)"] -.-> VSE
```

从摄像头到网络，视频经[采集](https://daiw.org/manual/webrtc/video-source-encoder) → [自适应调度](https://daiw.org/manual/webrtc/video-adaptation) → [编码](https://daiw.org/manual/webrtc/video-encoder-abstraction) → [打包](https://daiw.org/manual/webrtc/video-packetization)，一路把“大而恒定的原始画面”压成“贴合网络的包流”。

## 小结与下一章

**打包**把一帧压缩视频切成多个 [RTP 包](https://daiw.org/manual/webrtc/rtp-packet)（共享时间戳、序号连续、[marker 位](https://daiw.org/manual/webrtc/rtp-packet)标帧尾）。关键是**懂编解码器结构地切**——每种编解码器有专属打包格式（H264 按 [NALU](https://daiw.org/manual/webrtc/video-packetization)、VP8 按分区、VP9/AV1 带 [SVC 层信息](https://daiw.org/manual/webrtc/simulcast-svc)），按语义边界切才利于[丢包恢复](https://daiw.org/manual/webrtc/video-decode-recovery)，层信息还让 [SFU](https://daiw.org/manual/webrtc/sframe) 不解码就能[丢层](https://daiw.org/manual/webrtc/simulcast-svc)。接收侧对应**解包**。**发送侧至此完整**。

接下来转到接收侧。收到的包[乱序、有缺、抖动](https://daiw.org/manual/webrtc/rtp-packet)，第一关是**抖动缓冲 + 组帧**——把破碎的包流重建成完整、有序的帧。下一章。👉 [视频抖动缓冲与组帧](https://daiw.org/manual/webrtc/video-jitter-buffer)。

## 参考资料

- [1] libwebrtc 源码.`modules/rtp_rtcp/source/rtp_packetizer_*.h`（各编解码器打包器）、`rtp_format.h`。
- [2] IETF RFC 7741（VP8）、RFC 6184（H264）、RFC 7798（H265）、AV1 RTP。
- [3] 关联[接收侧组帧](https://daiw.org/manual/webrtc/video-jitter-buffer)。
