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

相关推荐
2601_955662461 天前
AI 配音工具 7 款实测:短视频、影视解说、小说推文音质横向对比
人工智能·音视频·语音识别·视频
阿童木写作1 天前
跨境电商图片翻译工具,批量翻译视频字幕一键抠图
人工智能·python·音视频
深圳市宝华视联2 天前
医院内网部署手术示教系统注意事项
嵌入式硬件·实时互动·音视频·实时音视频·视频编解码·嵌入式实时数据库
小柯南敲键盘2 天前
跨境电商图片翻译工具,批量处理视频字幕与抠图
人工智能·python·音视频
weixin_433417672 天前
阿里视频大模型wan2.7‑t2v,可以生成视频
人工智能·python·音视频
阿童木写作2 天前
跨境电商图片翻译工具,批量翻译视频字幕还免费
python·音视频
stuartevil2 天前
AI图生视频常见坑:参考图风格不一致怎么解决
人工智能·深度学习·音视频
贾宝玉的玉宝贾2 天前
FreeSWITCH 简单图形化界面 63 - 编写 mod_avsource 模块,将 RTSP/RTMP 源桥接为视频通道
音视频·voip·freeswitch·ippbx·pbx·sip通信
Blockchina2 天前
5个开源AI视频项目怎么选?从脚本、分镜到Shorts和剪映自动化
人工智能·开源·音视频
要开心吖ZSH2 天前
腾讯 IM × TRTC 联动实战:后端如何撑起一次视频问诊(混流录制篇)
java·音视频·腾讯云·健康医疗·即时通讯·im