AV1 码流 RTP 封装

注:近期文章均来自我的个人笔记,现在公开到博客上。如果有错误,欢迎指正。

一、整体码流结构

javascript 复制代码
 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|V=2|P|X|  CC   |M|     PT      |       sequence number         |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                           timestamp                           |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|           synchronization source (SSRC) identifier            |
+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
|            contributing source (CSRC) identifiers             |
|                             ....                              |
+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
|         0x100         |  0x0  |       extensions length       |
+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
|      ID       |  hdr_length   |                               |
+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+                               |
|                                                               |
|          dependency descriptor (hdr_length #bytes)            |
|                                                               |
|                               +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                               | Other rtp header extensions...|
+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
| AV1 aggr hdr  |                                               |
+-+-+-+-+-+-+-+-+                                               |
|                                                               |
|                   Bytes 2..N of AV1 payload                   |
|                                                               |
|                               +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                               :    OPTIONAL RTP padding       |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

关键说明

  • RTP 包的 Payload Type 可以由 SDP 协商决定
  • Dependency Descriptor 扩展头非必须,但是 WebRTC 在使用 AV1 时是强制启用的。原因是缺少该扩展头的话,无法区分 SVC 编码中不同的时域帧和空域帧
  • Aggregation header 位于 RTP 头 + 扩展头之后的第一个字节。官方文档并没有说明是否必须使用,但是在 WebRTC 的实现中是每个包都会加的

WebRTC 打包说明

以下 3 种 OBU 类型会被丢弃:

  • OBU_TEMPORAL_DELIMITER
  • OBU_TILE_LIST
  • OBU_PADDING

WebRTC 打包代码位于:

  • src\modules\rtp_rtcp\source\rtp_packetizer_av1.cc
  • src\modules\rtp_rtcp\source\rtp_packetizer_av1.h

二、Dependency Descriptor 扩展头结构

SVC 编码时需要用到,后续的 《SVC 编码技术》 再介绍


三、Aggregation Header

占用一个字节,结构如下:

javascript 复制代码
 0 1 2 3 4 5 6 7
+-+-+-+-+-+-+-+-+
|Z|Y| W |N|-|-|-|
+-+-+-+-+-+-+-+-+

字段说明

比特位 字段 说明
bit 0 Z 如果当前 RTP 包的第一个 OBU 是前一个 RTP 包中 OBU 的延续部分,则设置为 1;否则为 0
bit 1 Y 如果当前 RTP 包的最后一个 OBU 是一个片段,且将在下一个 RTP 包中继续,则设置为 1;否则为 0
bits 2-3 W 表示当前 RTP 包中包含的 OBU 元素的数量
bit 4 N 如果当前 RTP 包是一个编码视频序列(coded video sequence)的第一个包,则设置为 1;否则为 0

W 位详细说明

  • 如果设置为 0,则每个 OBU 元素前必须有一个长度字段(超过 3 个,则固定设为 0)
  • 如果设置为非 0 值(即 1、2 或 3 ),则最后一个 OBU 元素前不应有长度字段,其长度可通过以下方式计算:
    • 最后一个 OBU 的长度 = RTP Payload 的总长度 - Aggregation Header 的长度 - 前面所有 OBU(包括其长度字段)的总长度
  • 非 0 时,读取长度字段的次数 = W - 1
    • 例如:W = 1 时,表示只有一个 OBU 元素,并且读取 1 - 1 = 0 次长度字段,也就是 Aggregation header 之后直接为 OBU 元素数据

W 位设置示例

示例 1:W = 0(每个 OBU 前都有长度字段)
javascript 复制代码
 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|Z|Y|0 0|N|-|-|-|  OBU element 1 size (leb128)  |               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+               |
:                                                               :
:                      OBU element 1 data                       :
:                                                               :
|                                                               |
|                               +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                               |  OBU element 2 size (leb128)  |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
:                                                               :
:                       OBU element 2 data                      :
:                                                               :
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
:                                                               :
:                              ...                              :
:                                                               :
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|OBU e... N size|                                               |
+-+-+-+-+-+-+-+-+       OBU element N data      +-+-+-+-+-+-+-+-+
|                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
示例 2:W = 2(最后一个 OBU 前无长度字段)
javascript 复制代码
 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|Z|Y|1 0|N|-|-|-|  OBU element 1 size (leb128)  |               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+               |
|                                                               |
:                                                               :
:                      OBU element 1 data                       :
:                                                               :
|                                                               |
|                               +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                               |                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                               |
|                                                               |
:                                                               :
:                      OBU element 2 data                       :
:                                                               :
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

注:

W = b10 = 2
leb128 格式见上篇《AV1 视频编码技术》

封装示例

单个 OBU 封装示例
javascript 复制代码
- Z:0(不是前一个包的延续)
- Y:0(OBU 不会在下一个包中继续)
- W:1(包含一个 OBU 元素)
- N:1(如果是编码视频序列的第一个包,如 Sequence Header OBU)
多个 OBU 封装示例
javascript 复制代码
- Z:0(不是前一个包的延续)
- Y:0(OBU 不会在下一个包中继续)
- W:2(包含 2 个 OBU 元素)
- N:1(如果是编码视频序列的第一个包,如 Sequence Header OBU + Frame Header OBU 合封时,设置为 1)
OBU 分片封装示例
javascript 复制代码
第一个分片:

- Z:0(不是前一个包的延续)
- Y:1(OBU 将在下一个包中继续)
- W:1(包含一个 OBU 元素)
- N:0(不是编码视频序列的第一个包)

Aggregation Header:`01111000`,即 0x78

中间分片:

- Z:1(是前一个包的延续)
- Y:1(OBU 将在下一个包中继续)
- W:1(包含一个 OBU 元素)
- N:0(不是编码视频序列的第一个包)

Aggregation Header:`11101000`,即 0xE8

最后一个分片:

- Z:1(是前一个包的延续)
- Y:0(OBU 不会在下一个包中继续)
- W:1(包含一个 OBU 元素)
- N:0(不是编码视频序列的第一个包)

四、参考文档

AV1 RTP 封装规范

相关推荐
愚公搬代码2 小时前
【愚公系列】《剪映+DeepSeek+即梦:短视频制作》055-即梦+DeepSeek生成AI视频(文生视频案例)
人工智能·音视频
l14372332672 小时前
AI电影解说的技术链路拆解:从视频理解到自动剪辑
人工智能·音视频
飞睿科技3 小时前
ESP32-S31 高性能 AIoT SoC 在智能音频领域的应用实践
音视频·esp32·智能家居·乐鑫科技·ai智能
AI2512243 小时前
免费AI视频生成工具技术解析与功能对比
人工智能·音视频
EasyCVR4 小时前
国标GB28181视频监控平台EasyCVR视频质量诊断赋能智慧城市精细化治理
人工智能·音视频·智慧城市
炭烤毛蛋5 小时前
rk3588 适配音频解码芯片 es8388
arm开发·音视频·rk3588·es8388
孤岛站岗5 小时前
WAN:万象视频,开源视频生成的新标杆
开源·音视频
AI2512245 小时前
AI生视频主流工具功能及生成技术原理解析
人工智能·音视频
reasonsummer5 小时前
【教学类-160-01】20260408 AI视频培训-练习1“豆包AI视频”
人工智能·音视频