当前位置: 首页 > news >正文

AV1 码流 RTP 封装

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

一、整体码流结构

012301234567890123456789012345678901+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+|V=2|P|X|CC|M|PT|sequence number|+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+|timestamp|+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+|synchronizationsource(SSRC)identifier|+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+|contributingsource(CSRC)identifiers||....|+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+|0x100|0x0|extensions length|+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+|ID|hdr_length||+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+||||dependencydescriptor(hdr_length #bytes)||||+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+||Other rtp header extensions...|+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+|AV1aggr hdr||+-+-+-+-+-+-+-+-+||||Bytes2..NofAV1payload||||+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+|:OPTIONALRTPpadding|+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

关键说明

  • 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

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

01234567+-+-+-+-+-+-+-+-+|Z|Y|W|N|-|-|-|+-+-+-+-+-+-+-+-+

字段说明

比特位字段说明
bit 0Z如果当前 RTP 包的第一个 OBU 是前一个 RTP 包中 OBU 的延续部分,则设置为 1;否则为 0
bit 1Y如果当前 RTP 包的最后一个 OBU 是一个片段,且将在下一个 RTP 包中继续,则设置为 1;否则为 0
bits 2-3W表示当前 RTP 包中包含的 OBU 元素的数量
bit 4N如果当前 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 前都有长度字段)
012301234567890123456789012345678901+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+|Z|Y|00|N|-|-|-|OBUelement1size(leb128)||+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+|:::OBUelement1data:::|||+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+||OBUelement2size(leb128)|+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+:::OBUelement2data:::||+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+:::...:::+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+|OBUe...Nsize||+-+-+-+-+-+-+-+-+OBUelementNdata+-+-+-+-+-+-+-+-+||+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
示例 2:W = 2(最后一个 OBU 前无长度字段)
012301234567890123456789012345678901+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+|Z|Y|10|N|-|-|-|OBUelement1size(leb128)||+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+|||:::OBUelement1data:::|||+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+|||+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+|||:::OBUelement2data:::||+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

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

封装示例

单个 OBU 封装示例
-Z0(不是前一个包的延续)-Y0OBU不会在下一个包中继续)-W1(包含一个OBU元素)-N1(如果是编码视频序列的第一个包,如 Sequence HeaderOBU
多个 OBU 封装示例
-Z0(不是前一个包的延续)-Y0OBU不会在下一个包中继续)-W2(包含2OBU元素)-N1(如果是编码视频序列的第一个包,如 Sequence HeaderOBU+Frame HeaderOBU合封时,设置为1
OBU 分片封装示例
第一个分片:-Z0(不是前一个包的延续)-Y1OBU将在下一个包中继续)-W1(包含一个OBU元素)-N0(不是编码视频序列的第一个包) Aggregation Header:`01111000`,即0x78中间分片:-Z1(是前一个包的延续)-Y1OBU将在下一个包中继续)-W1(包含一个OBU元素)-N0(不是编码视频序列的第一个包) Aggregation Header:`11101000`,即0xE8最后一个分片:-Z1(是前一个包的延续)-Y0OBU不会在下一个包中继续)-W1(包含一个OBU元素)-N0(不是编码视频序列的第一个包)

四、参考文档

AV1 RTP 封装规范

http://www.cnnetsun.cn/news/1772278.html

相关文章:

  • 老旧电脑焕新:OpenClaw+Phi-3-vision-128k-instruct打造智能辅助系统
  • 采购人员定位系统前,先问厂商这十个问题
  • 电脑硬件说明
  • M5GFX嵌入式图形库:面向M5Stack的HAL解耦GUI引擎
  • 【多模态大模型——跨越感知与认知的鸿沟】第2章 视觉感知层:编码器架构与表征工程
  • 为什么你的PHP 8.9异步服务仍卡在I/O?3个致命配置错误+2套生产环境验证方案
  • Python 3.14 JIT编译器实测对比:启动快3.8倍、CPU占用降62%——这7个配置参数90%开发者从未启用
  • 可信AI:政务智能化建设中的伦理与安全框架
  • 避坑!这些毕设太好抄了,3000+毕设案例推荐第1042期
  • 做自媒体,我是怎么把“不知道写什么”变成“写不完”的
  • nanobot 源码解析(五):Skills 系统——让 AI 秒变专家贺
  • SEATA分布式事务——AT模式唐
  • 第一次学习c语言
  • 【数值分析】有限元法(FEM)数值不稳定性分析:$L^2$ 与 $H_0^1$ 空间的对比实验
  • 包装印刷行业VOCs治理,为什么企业选择“沸石转轮+RTO”?
  • 2026年,AI CRM跑步进入2.0时代
  • 【限时技术窗口期】C# 13委托优化仅在.NET 8.0.3–8.0.6中默认启用,错过将多承担18个月性能债务
  • OpenClaw+百川2-13B量化模型:5步完成飞书机器人接入与对话触发
  • 2026年定制软件开发公司优选指南
  • Infoseek舆情系统新视角:真正的杂音不是音量小,而是价值低——从信号识别到战略预判
  • 数码管字符对照表
  • CCF期刊目录最新查询指南:2022年最全下载与使用攻略
  • 图论实战:从基准法到并查集+LCA,全面解析无向图中桥的高效查找策略
  • PhotoKit在线图片编辑器:一站式解决你的图片处理需求
  • EhViewer:全方位画廊资源高效管理与体验优化深度解析
  • 为什么你的C# 13主构造函数反而变慢了?揭秘字段初始化顺序、属性注入与依赖解析的致命时序冲突
  • 提升用户体验:用AOS.js为Vue3应用添加优雅的滚动动画效果
  • 2026 中国律所数字化转型工具选型指南
  • 告别虚拟机!在WSL2的Ubuntu 20.04上搞定OpenCV 4.5+完整开发环境(含GUI显示配置)
  • OpenClaw模型量化实践:Qwen2.5-VL-7B-GPTQ在消费级显卡上的优化部署