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

RTP载荷H264(实战细节)

        RTP包由两部分组成,RTP头和RTP载荷:

RTP头

        RTP头的 结构如下:

代码结构:

typedef struct RtpHdr
{uint8_t cc : 4,  			// CSRC countx : 1,   			// header extendp : 1,   			// padding flagversion : 2;		// versionuint8_t pt : 7,				// payload typem : 1;				// mark bituint16_t seq;				// sequence number;uint32_t ts;				// timestampuint32_t ssrc;				// sync source
}RtpHdr;

v :        RTP协议的版本号,当前的RTP版本号为2.

p :        填充标志, 如果p=1,则在该报文的尾部填充一个或多个额外的八位组,它们不是有效载荷的一部分。

x :        扩展标志,如果x=1,则在RTP报头后跟有一个扩展报头.

cc :       CSRC计数器,指示CSRC 标识符的个数

m :        标记,编辑帧的开始和结束,例如一帧的数据比较大,分成了好多RTP包进行传输,则最后一包m=1带包一帧数据传输完成,其他包m=0。

pt :        有效荷载类型,用于说明RTP报文中有效载荷的类型。一般都是用96-127.

seq :      用于标识发送者所发送的RTP报文的序列号,每发送一个报文,序列号增1, 不同的源有独立的计数体制,如音频视频的seq是独立的。这个序列号的初始值可以为0但是也可以为其它随机值,只要符合+1就行;

ts :       时间戳

ssrc :    用于标识同步信源。该信源的值是自定义的,可以使用time(NULL)赋值。

RTP载荷

        RTP载荷根据帧数据的大小可以分为三种模式:单包,分片包,聚合包

单包:

        帧数据和RTP头总数不大于网络传输MTU,就可以采用单包,一个RTP包包含一帧数据。

分片包:

        帧数据比较大,在网络传输时由于MTU的限制就会采用分片策略,将一个数据帧分成多个RTP包进行传输。

分片传输有两种类型:

FU-A:

数据组成:

 载荷会有两个字节的RTP载荷信息描述。

FU indication:

|0|1|2 |3|4|5|6|7|

|F|NRI|    Type  |

        FU indication 的前三个bit(F NRI)和H264开始码后的第一个字节的前三个bit是一样的,H264类型字节:

nal_unit_head{forbidden_zero_bit(1bit):禁止位 == Nnal_ref_idc(2bit): == NRInal_unit_type(5bit):NALU类型
};

Type是FU-A的类型28.

FU header

|0| 1|2|3|4|5|6|7|

|S|E|R|   Type   |

S:帧数据的第一个RTP包,该标志置1, 其他RTP包置0.

E:帧数据的最后一个RTP包,该标志置1,其他RTP包置0.

R:   设置为0

Type:H264的NALU的第一个字节的类型,及上图中的nal_unit_type(5bit):NALU类型

        FU indication和FU header之后便是H264的载荷数据,该载荷数据去掉了H264的起始码和起始码后的第一个字节, 因为该字节的信息已经全部由FU indication和FU header包含。

实例:

H264数据:

        00 00 00 01 65 xx xx xx xx xx xx xx...

RTP数据:

        RTP头 FUindication FUheader xx xx xx xx xx xx xx...

FU-B:

         相较于FU-A,该模式多了个两字节的DON(解码顺序号)字段, FU-B的FU indication的Type是29。一般都是用FU-A.

聚合包:

         即帧数据比较少,多个帧打包在一个RTP包中。

         现实中,单包,分片包比较常用。

http://www.lryc.cn/news/38701.html

相关文章:

  • 软考高级信息系统项目管理师系列之四十三:信息系统安全管理
  • 并发编程之AtomicUnsafe
  • GDB调试快速入门
  • Vim一次复制,多次粘贴
  • 如何修改Win11上的默认程序?
  • 安装Linux虚拟机和Hadoop平台教程汇总及踩坑总结
  • Shell脚本的使用和介绍
  • 机械学习 - 基础概念 - scikit-learn - 数据预处理 - 1
  • OLCNE cluster 配置 NFS Storage(英文)
  • RabbitMQ高级特性
  • 利用Dockerfile开发定制镜像实战.
  • PyInstaller 将DLL文件打包进exe
  • 【JVM篇2】垃圾回收机制
  • LeetCode598. 范围求和 II(python)
  • 观察者模式与发布订阅模式
  • 磨金石教育摄影技能干货分享|烟花三月下扬州,是时候安排了!
  • Kafka 消费组位移
  • Python|数学|贪心|数组|动态规划|单选记录:实现保留3位有效数字(四舍六入五成双规则)|用Python来创造一个提示用户输入数字的乘法表|最小路径和
  • 【MySQL】MySQL的索引
  • 弱监督实例分割 Box-supervised Instance Segmentation with Level Set Evolution 论文笔记
  • Springboot是什么
  • LeetCode 134. 加油站(函数图像法 / 贪心)
  • 王道计算机组成原理课代表 - 考研计算机 第三章 存储系统 究极精华总结笔记
  • Flask-mock接口数据流程
  • springboot项目配置序列化,反序列化器
  • c++11 标准模板(STL)(std::unordered_map)(九)
  • Seay代码审计工具
  • 界面开发(4)--- PyQt5实现打开图像及视频播放功能
  • 核心系统国产平台迁移验证
  • 【数据结构之二叉树】——二叉树的概念及结构,特殊的二叉树和二叉树性质