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 封装规范

相关推荐
辰辰观影36 分钟前
Windows网盘视频播放器推荐:无广告4K HDR怎么选
音视频
2601_966827452 小时前
电视端云盘在线播放怎么选?支持4K HDR的应用推荐
音视频
开开心心就好3 小时前
音频降噪剪辑工具,音量裁剪一键处理
运维·服务器·前端·spring·ocr·音视频·1024程序员节
AI视频工具指南7 小时前
AI视频的声音和画面怎么配合?先分清谁在传递信息
人工智能·aigc·音视频
辰辰观影9 小时前
无广告播放器推荐来啦
音视频
TrueDei9 小时前
GStreamer 使用 valve 分别控制音视频流的暂停与恢复
音视频
一条破秋裤10 小时前
基于 Hi3516CV610 的立定跳远视频测量系统调研与实施方案
arm开发·音视频
2601_9668274511 小时前
视频里的特效字幕怎么翻译?外挂字幕与AI字幕一键处理教程
音视频
21岁被迫秃头12 小时前
SVT-AV1 Mini-Gop决策算法详解+源码分析.md
算法·av1·svt-av1·源码详解·mini-gop决策
八月的雨季 最後的冰吻12 小时前
音视频面试--延迟优化
面试·职场和发展·音视频