RTP协议基本分析(RTSP、WebRTC使用)

目录

  • 1、介绍
  • 2、RTP
  • 3、格式
  • 4、RTP打包H264
    • 4.1、H264打包方式之Single NAL Unit
    • 4.2、H264打包方式之FU-A
      • 4.2.1、FU indication
      • 4.2.2、FU header
      • 4.2.3、第一个IDR帧的NALU第一个切片
      • 4.2.4、第一个IDR帧的NALU第二个切片
      • 4.2.5、第一个IDR帧的NALU最后一个切片
  • 5、RTP打包AAC
    • 5.1、AU-headers-length
    • 5.2、AU-header
    • 5.3、AU
    • 5.4、RTSP/SDP中AAC相关配置
    • 5.5、AU-Header数据段的格式

1、介绍

实时流传输协议(RTSP:Real Time Streaming Protocol)是一种网络传输协议,旨在发送低延迟流。
该协议由RealNetworks,Netscape和哥伦比亚大学的专家在1996年开发。它定义了应如何打包流中的数
据以进行传输。
在这里插入图片描述

2、RTP

RTP协议原理,负责对流媒体数据进行封包并实现媒体流的实时传输,即它按照RTP数据包格式来封装流媒体数据,并利用与它绑定的协议进行数据包的传输。

RTP可以基于UDP和TCP两种方式传输,两种方式大致是一样的,下面主要都是基于UDP的分析:

RTP在端口号1025到65535之间选择一个未使用的偶数UDP端口号,而在同一次会话中的RTCP则使用下一个基数UDP端口号。

3、格式

RTP报文由两部分组成:报头和有效载荷。RTP报头格式如下图所示,其中:V:RTP协议的版本号,占2位,当前协议版本号为2。P:填充标志,占1位,如果P=1,则在该报文的尾部填充一个或多个额外的八位组,它们不是有效载荷
的一部分。X:扩展标志,占1位,如果X=1,则在RTP报头后跟有一个扩展报头。
CC:CSRC计数器,占4位,指示CSRC 标识符的个数。M: 标记,占1位,不同的有效载荷有不同的含义,对于视频,标记一帧的结束;对于音频,标记帧的开
始。PT: 有效载荷类型,占7位,用于说明RTP报文中有效载荷的类型,如GSM音频、JPEM图像等。
序列号:占16位,用于标识发送者所发送的RTP报文的序列号,每发送一个报文,序列号增1。接收者
通过序列号来检测报文丢失情况,重新排序报文,恢复数据。时戳(Timestamp):占32位,时戳反映了该RTP报文的第一个八位组的采样时刻。接收者使用时戳来
计算延迟和延迟抖动,并进行同步控制。同步信源(SSRC)标识符:占32位,用于标识同步信源。该标识符是随机选择的,参加同一视频会议的
两个同步信源不能有相同的SSRC。特约信源(CSRC)标识符:每个CSRC标识符占32位,可以有015个。每个CSRC标识了包含在该RTP
报文有效载荷中的所有特约信源。

在这里插入图片描述

1 typedef struct _rtp_header_t
2 {
3 uint32_t v:2; /* protocol version */
4 uint32_t p:1; /* padding flag */
5 uint32_t x:1; /* header extension flag */
6 uint32_t cc:4; /* CSRC count */
7 uint32_t m:1; /* marker bit */
8 uint32_t pt:7; /* payload type */
9 uint32_t seq:16; /* sequence number */
10 uint32_t timestamp; /* timestamp */
11 uint32_t ssrc; /* synchronization source */
12 } rtp_header_t;

同步信源:是指产生媒体流的信源,例如麦克风、摄像机、RTP混合器等。它通过RTP报头中的一个32位数
字SSRC标识符来标识,而不依赖于网络地址,接收者将根据SSRC标识符来区分不同的信源,进行RTP报
文的分组。

特约信源:是指当混合器接收到一个或多个同步信源的RTP报文后,经过混合处理产生一个新的组合RTP报
文,并把混合器作为组合RTP报文的SSRC,而将原来所有的SSRC都作为CSRC传送给接收者,使接收者
知道组成组合报文的各个SSRC。
在这里插入图片描述
例如:
有三个信号源各发出一路rtp流,RTP1携带的SSRC是SSRC1,RTP2携带的SSRC是SSRC2,
RTP3携带SSRC3,这三路RTP流到达混合器时,混合器会将这三路流混合成一路流发出去,它会把这三
路流的SSRC记录下来,形成一个列表,叫CSRC表,在发送的混合RTP流中,SSRC域填充的字段是混合
器本身的SSRC4,而CSRC字段则会根据该包的负载的源来填入。

如当前的RTP包的负载是来自SSRC1的,那么在当前RTP包的CSRC字段填入SSRC1。
这样接收者就可以根据CSRC来区分不同的信源。

4、RTP打包H264

RTP的特点不仅仅支持承载在UDP上,这样利于低延迟音视频数据的传输,另外一个特点是它允许
通过其它协议接收端和发送端协商音视频数据的封装和编解码格式,这样固定头的playload type字
段就比较灵活。

H.264标准协议定义了两种不同的类型:一种是VCL即Video Coding Layer , 一 种 是 NAL 即
Network Abstraction Layer。其中前者就是编码器吐出来的原始编码数据,没有考虑传输和存储
问题。后面这种就是为了展现H.264的网络亲和性,对VCL输出的slice片数据进行了封装为
NALUs(NAL Units),然后再封装为RTP包进行传输。

NALU的基本格式是:NALU Header + NALU Data,其中NALU的头由一个字节组成如下所示:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
一、
1-11就是NALU的单个包类型,但是一个NALU的大小是不一样的,如果是非视频数据的
SPS PPS才十几个字节,对于IDR帧,则有可能几十KB。
这样把NALU打包到RTP方式就很多,分为:
一个RTP包承载一个NALU;
多个NALU合并到一个RTP;
一个大的NALU切分成多个RTP。

二、
同时由于时间戳的问题,就有了24-29几种类型。
但是对于发送端组RTP包的一方来说,尽可能找简单的打包方式。对于接受端则需要适配各种发送
端的打包方式,因为无法决定输入源的打包方式。
(打包的时候不要搞太复杂的模式)

  1. 我们对于NALU的长度<=1400(rtp payload size)的则采用的是单一NALU打包到单一的RTP
    包中;
  2. 我们对于NALU的长度>1400的则采用了FU-A的方式进行了打包,这种就是把一个大的NALU进
    行了切分,最后接收方则进行了合并,把多个RTP包合并成一个完整的NALU即可;
  3. 为什么NALU的长度大于1400字节就要进行FU-A切片,是因为底层MTU大小值一般为1500,从
    传输效率讲,使用1400作为切分条件。
    RTP最大数据包(包含RTP头部) = MTU - UDP首部 - IP 报文首部

4.1、H264打包方式之Single NAL Unit

一个RTP包打包一个单独的NALU方式,其实最好理解,就是在RTP固定头后直接填充NLAU
单元数据即可,即:
RTP Header + NALU Header + NALU Data; (不包括startcode)
文件中的SPS:
在这里插入图片描述
RTP包中的SPS:
在这里插入图片描述

4.2、H264打包方式之FU-A

需要了解两个数据包头即FU indicator和Fu header。

4.2.1、FU indication

在这里插入图片描述
这里面的的F和NRI就是NALU头的前面三个bit位,后面的
TYPE就是NALU的FU-A类型28,这样在RTP固定头后面第一字节的后面5bit提取出来就确认了该
RTP包承载的不是一个完整的NALU,是其一部分。

那么问题来了,一个NALU切分成多个RTP包传输,那么到底从哪里开始哪里结束呢?
可能有人说RTP包固定头不是有mark标记么,注意区分那个是以帧图像的结束标记,这里要确定是NALU结束
的标记,其次NALU的类型呢?那么就需要RTP固定12字节后面的Fu Header来进行区分。

4.2.2、FU header

在这里插入图片描述

字段解释:
S: 1 bit 当设置成1,开始位指示分片NAL单元的开始。当跟随的FU荷载不是分片NAL单元荷载的开
始,开始位设为0。E: 1 bit 当设置成1, 结束位指示分片NAL单元的结束,即, 荷载的最后字节也是分片NAL单元的最后
一个字节,当跟随的FU荷载不是分片NAL单元的最后分片,结束位设置为0。
也就是说一个NALU切片时,第一个切片的SE是10,然后中间的切片是00,最后一个切片时11。R: 1 bit
保留位必须设置为0,接收者必须忽略该位。Type: 5 bits
此处的Type就是NALU头中的Type,1-23的那个值,表示 NAL单元荷载类型定义。

4.2.3、第一个IDR帧的NALU第一个切片

在这里插入图片描述

FU indication:
十六机制:0x7C
二进制:0111 1100
FU header:
十六进制:0x85
二进制:1000 0101
这里的SE是10,则说明该RTP包承载的NALU的第一个切片。

4.2.4、第一个IDR帧的NALU第二个切片

在这里插入图片描述

FU indication:
十六机制:0x7C
二进制:0111 1100
FU header:
十六进制:0x05
二进制:0000 0101
这里的SE是00,则说明该RTP包承载的NALU的中间切片。

4.2.5、第一个IDR帧的NALU最后一个切片

在这里插入图片描述

FU indication:
十六机制:0x7C
二进制:0111 1100
FU header:
十六进制:0x45
二进制:0100 0101
这里的SE是01,则说明该RTP包承载的NALU的最后一个切片。

5、RTP打包AAC

过程:

  1. 需要将aac的前7个(或9个)字节的ADTS去掉,即是跳过adts header。
  2. 添加RTP Header。
  3. 添加AU_HEADER_LENGTH。
  4. 添加AU_HEADER。
  5. 添加AU(去掉ADTS的aac数据)数据。

如:

注意:一个RTP包中可以有一个AU-headers-length 和 n个AU-header和 n个AU(AU每包实际音频数据流)

5.1、AU-headers-length

头两个字节表示au-header的长度,单位是bit。 一个AU-header长度是两个字节(16bit)因为可以有多
个au-header所以AU-headers-length的值是 16的倍数,一般音频都是单个音频数据流的发送,所以
AU-headers-length的值是16
//AU_HEADER_LENGTH
bytes[12] = 0x00; //高位
bytes[13] = 0x10; //低位 只有一个AU_HEADER
因为单位是bit, 除以8就是auHeader的字节长度;又因为单个auheader字节长度2字节,所以再除以2就
是auheader的个数。
(注意:AU-header长度并不是固定为2字节,具体要看SDP)

5.2、AU-header

au-header的高13个bits就是一个au 的字节长度:
//AU_HEADER
bytes[14] = (byte)((len & 0x1fe0) >> 5); //高位
bytes[15] = (byte)((len & 0x1f) << 3); //低位
(注意:AU-header长度并不是固定为2字节,具体要看SDP)

5.3、AU

音频实际数据(去掉ADTS的aac数据)

5.4、RTSP/SDP中AAC相关配置

1 v=0
2 o=- 16128587303007558182 16128587303007558182 IN IP4 WINDOWS-75ID
U9Q
3 s=Unnamed
4 i=N/A
5 c=IN IP4 0.0.0.0
6 t=0 0
7 a=tool:vlc 3.0.5
8 a=recvonly
9 a=type:broadcast
10 a=charset:UTF-8
11 a=control:rtsp://192.168.2.195:8554/
12 m=audio 0 RTP/AVP 96
13 b=AS:128
14 b=RR:0
15 a=rtpmap:96 mpeg4-generic/22050
16 a=fmtp:96 streamtype=5; profile-level-id=15; mode=AAC-hbr; config
=138856e500; sizeLength=13; indexLength=3; indexDeltaLength=3; Pr
ofile=1;
17 a=control:rtsp://192.168.2.195:8554/trackID=4
18 m=video 0 RTP/AVP 96
19 b=AS:800
20 b=RR:0
21 a=rtpmap:96 H264/90000
22 a=fmtp:96 packetization-mode=1;profile-level-id=42c01e;sprop-para
meter-sets=Z0LAHtoCQKeX/8CgAJ/EAAADAZAAAF2qPFi6gA==,aM43IA==;
23 a=control:rtsp://192.168.2.195:8554/trackID=5

streamtype对于AAC, 固定为5。
profile-level-id固定为1。
config, SizeLength, IndexLength, IndexDeltaLength作用:
config是16进制的, 前两个字节 1388 , 表示采样率为22050, 1个channel。
前两个字节的为ios-14996-3中定义的AudioSpecificConfig, 前13个bits的格式为:
在这里插入图片描述
samplingFrequencyIndex的取值:
在这里插入图片描述
1388 转换成2进制为 0001 0011 1000 1000
audioObjectType为 00010 , 即 2
samplingFrequencyIndex为 0111 , 即 7 , 对应的采样频率为 22050
channelConfiguration为 0001 , 表示channel数量为1。

sizeLength=13; indexLength=3; indexDeltaLength=3涉及到音频的AU Header。

5.5、AU-Header数据段的格式

在这里插入图片描述
在这里插入图片描述

其它的值都是可选的, 如果sdp中没有出现相关的参数(或者为0), 则表示它们不出现。
以最简单的情况举例, 假设aac数据长度为200字节, 只有一个au-header。
200 的二进制为 0000011001000。 (补足为13 bits)
AU-headers-length 值为16, 因为只有一个au-header, au-header中
只有AU-size和AU-Index, 共占用16bits。

整个au-header数据段的内容为

0000 0000 0000 1000 0000011001000 000

如果一个rtp中只有一个aac包, 不需要加AU-Header, 那么sdp中的aac参数可以简化为

a=fmtp:96 streamtype=5; profile-level-id=1; mode=AAC-hbr; config=1
38856e500;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/378871.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

对照片进行边缘化处理,并将边缘化处理后的结果保存

对照片进行边缘化处理&#xff0c;并将边缘化处理后的结果保存 import cv2 from matplotlib import pyplot as plt img cv2.imread(E:\Python-workspace\OpenCV\OpenCV/water1.png,1)#第一个参数为选择照片的路径&#xff0c;注意照片路径最后一个为正斜杠其他都为反斜杠&…

fastjson转换时有大括号或者冒号或者有中括号_[Python Basic] 字符串处理以及类型转换 1...

String Manipulation & Typecasting (1)1. 文本复制以及连接1.1 Multiply sign使用 multiply sigh/乘号* 来复制文本片段。乘号复制文本举例&#xff1a; print("Hi" * 3) # output: HiHiHi print("*" * 10)# output:**********1.2 连接1.2.1 使用 plu…

读《深入分析Java Web技术内幕》

这里这本书的预读章节&#xff0c;看完预读部分&#xff0c;解答了一些疑惑&#xff0c;也相信这是一本夯实Java Web架构体系的好书。 HTTP协议解析 开发一般使用firefox的firebug调试&#xff0c;这的确是一个利器&#xff0c;HTTP的请求头响应头一目了然。 浏览器缓存机制 当…

RTSP协议基本分析

目录一、介绍二、RTSP与HTTP三、RTSP推流基本过程1、OPTION 查询服务器端可用方法1.1、Client 请求1.2、Server 回复2、ANNOUNCE 发送媒体描述信息2.1、Client 请求2.2、Server 回复3、SETUP建立RTSP会话3.1、Client 请求&#xff08;视频流&#xff09;3.2、Server 回复&#…

找取照片上的25个特征点,并保存结果

找取照片上的25个特征点&#xff0c;并保存结果 import numpy as np import cv2 from matplotlib import pyplot as plt img cv2.imread(E:\Python-workspace\OpenCV\OpenCV/water1.png,1)#第一个参数为选择照片的路径&#xff0c;注意照片路径最后一个为正斜杠其他都为反斜杠…

P2P技术详解(一):NAT详解——详细原理、P2P简介

目录1. IPv4协议和NAT的由来2. NAT的工作模型和特点2.1、NAT的概念模型2.2、一对一的NAT2.3、一对多的NAT2.4、按照NAT端口映射方式分类2.4.1全锥形NAT2.4.2限制锥形NAT2.4.3端口限制锥形NAT2.4.4对称型NAT3. NAT的限制与解决方案3.1、IP端到端服务模型3.2、NAT的弊端3.3、NAT穿…

显示照片的二维直方图

显示照片的二维直方图 import cv2 from matplotlib import pyplot as plt img cv2.imread(E:\Python-workspace\OpenCV\OpenCV/water1.png,1)#第一个参数为选择照片的路径&#xff0c;注意照片路径最后一个为正斜杠其他都为反斜杠&#xff1b;第二个参数&#xff0c;其中1表示…

周五怎么表示 mysql_完美起航-MySQL找每个月最后一个星期五--函数定义与使用

数据库作业有一道题是这样子的&#xff1a;有一张名叫emp的表记录员工信息&#xff0c;其中有如下字段 HIREDATE 表示员工被雇用的日期&#xff1a;然后问题是这样的&#xff1a;q7.Show details of employee hiredates and the date of their first payday.(Paydays occur on…

silverlight学习总结【完】

以下内容是个人理解&#xff0c;不保证正确性。且假设使用C#&#xff0c;并且有一定的相关知识和XML基础。 silverlight是什么&#xff0c;能做什么 silverlight用XAML来做前端界面&#xff0c;用.NET或者JS作为程序脚本支持&#xff0c;在浏览器内外运行的应用。可以认为和FLA…

P2P技术详解(二):P2P中的NAT穿越(打洞)方案详解

目录1、内容概述2、反向链接技术&#xff1a;一种特殊的P2P场景&#xff08;通信双方中只有一方位于NAT设备之后&#xff09;3、基于UDP协议的P2P打洞技术详解3.1、原理概述3.2、典型P2P情景1&#xff1a; 两客户端位于同一NAT设备后面&#xff08;即相同内网中&#xff09;3.3…

显示照片的RGB直方图

显示照片的RGB直方图 import numpy as np import cv2 as cv from matplotlib import pyplot as plt img cv.imread(E:\Python-workspace\OpenCV\OpenCV/BEYOND.png,1)#第一个参数为选择照片的路径&#xff0c;注意照片路径最后一个为正斜杠其他都为反斜杠&#xff1b;第二个参…

mysql慢查询开启语句分析_mysql慢查询语句分析总结

我们经常会接触到MySQL&#xff0c;也经常会遇到一些MySQL的性能问题。我们可以借助慢查询日志和explain命令初步分析出SQL语句存在的性能问题通过SHOW FULL PROCESSLIST查看问题SHOW FULL PROCESSLIST相当于select * from information_schema.processlist可以列出正在运行的连…

P2P技术详解(三):P2P中的NAT穿越(打洞)方案详解(进阶分析篇)

目录1、NAT和NAPT2、NAT带来的问题3、P2P通信穿越NAT的技术、方法4、NAT穿越技术1&#xff1a;应用层网关4.1、原理4.2、限制5、NAT穿越技术2&#xff1a;中间件技术5.1、原理5.2、限制6、NAT穿越技术3&#xff1a;打洞技术(Hole Punching)6.1、原理6.2、方法6.2.1NAT行为类型与…

将两大小完全相同的照片进行加权混合对比

将两张大小完全相同的照片进行加权混合对比 import cv2 img1cv2.imread(E:\Python-workspace\OpenCV\OpenCV/water1.png,1)#第一个参数为选择照片的路径&#xff0c;注意照片路径最后一个为正斜杠其他都为反斜杠&#xff1b;第二个参数&#xff0c;其中1表示所选照片为彩色照片…

P2P技术详解(四):P2P技术之STUN、TURN、ICE详解

目录1、内容概述2、STUN详解2.1 RFC3489/STUN2.1.1 报文结构2.1.2实现原理2.1.3STUN功能举例2.2 RFC5389/STUN2.2.1STUN用途2.2.2报文结构2.3 RFC5389与RFC3489的区别2.4 新特性介绍2.4.1指纹机制2.4.2通过DNS发现服务器机制2.4.3认证和消息完整性机制2.4.4备份服务器机制2.5 R…

比较两张大小相同的照片的差异,返回数值

比较两张大小相同的照片的差异&#xff0c;返回数值 from PIL import Image import math import operator from functools import reducedef image_contrast(img1, img2):image1 Image.open(img1)image2 Image.open(img2)h1 image1.histogram()h2 image2.histogram()resul…

poj2115C Looooops

http://poj.org/problem?id2115 参考人家的 如下 如i65534&#xff0c;当i3时&#xff0c;i1 其实就是 i(655343)%(2^16)1 有了这些思想&#xff0c;设对于某组数据要循环x次结束&#xff0c;那么本题就很容易得到方程&#xff1a; x[(B-A2^k)%2^k] /C 即 Cx(B-A)(mod 2^k) 此…

黑色背景下,计算照片白色的区域面积和周长

黑色背景下&#xff0c;计算照片白色的区域面积和周长 import cv2 img cv2.imread(E:\Python-workspace\OpenCV\OpenCV/beyond.png,1)#第一个参数为选择照片的路径&#xff0c;注意照片路径最后一个为正斜杠其他都为反斜杠&#xff1b;第二个参数&#xff0c;其中1表示所选照…

通俗易懂:快速理解P2P技术中的NAT穿透原理

目录1、基础知识1.1、什么是NAT&#xff1f;1.2、为什么会有NAT&#xff1f;1.3、NAT有什么优缺点&#xff1f;2、NAT的实现方式2.1、静态NAT2.2、NAPT3、NAT的主要类型3.1、完全锥型NAT&#xff08;Full Cone NAT&#xff0c;后面简称FC&#xff09;3.2、受限锥型NAT&#xff…

java 负载均衡_java负载均衡 - 岁月静好I的个人空间 - OSCHINA - 中文开源技术交流社区...

作用对系统的高可用&#xff0c;网络压力的缓解&#xff0c;处理能力扩容的重要手段之一。服务器负载我们通常所说的负载是指&#xff1a;服务器负载软硬件负载服务器负载又分为&#xff1a;软件负载--硬件负载软件负载&#xff1a;通过在服务器上安装一些具有负载功能或模块的…