rtsp的讲解

一、RTSP请求的常用方法

方法描述
OPTIONS 获取服务端提供的可用方法
DESCRIBE 向服务端获取对应会话的媒体描述信息
SETUP 向服务端发起建立请求,建立连接会话
PLAY 向服务端发起播放请求
TEARDOWN 向服务端发起关闭连接会话请求

二、 sdp格式
sdp格式由多行的type=value组成

sdp会话描述由一个会话级描述和多个媒体级描述组成。会话级描述的作用域是整个会话,媒体级描述描述的是一个视频流或者音频流

会话级描述由v=开始到第一个媒体级描述结束

媒体级描述由m=开始到下一个媒体级描述结束

下面是上面示例的sdp文件,我们就来好好分析一下这个sdp文件

v=0\r\n
o=- 91565340853 1 in IP4 192.168.31.115\r\n
t=0 0\r\n
a=contol:*\r\n
m=video 0 RTP/AVP 96\r\n
a=rtpmap:96 H264/90000\r\n
a=framerate:25\r\n
a=control:track0\r\n

这个示例的sdp文件包含一个会话级描述和一个媒体级描述,分别如下

会话级描述

v=0\r\n
o=- 91565340853 1 IN IP4 192.168.31.115\r\n
t=0 0\r\n
a=contol:*\r\n

v=0 表示sdp的版本

o=- 91565340853 1 IN IP4 192.168.31.115
格式为 o=<用户名> <会话id> <会话版本> <网络类型><地址类型> <地址>
用户名:-
会话id:91565340853,表示rtsp://192.168.31.115:8554/live请求中的live这个会话
会话版本:1
网络类型:IN,表示internet
地址类型:IP4,表示ipv4
地址:192.168.31.115,表示服务器的地址

媒体级描述

m=video 0 RTP/AVP 96\r\n
a=rtpmap:96 H264/90000\r\n
a=framerate:25\r\n
a=control:track0\r\n

m=video 0 RTP/AVP 96\r\n

格式为 m=<媒体类型> <端口号> <传输协议> <媒体格式 >
媒体类型:video

端口号:0,为什么是0?因为上面在SETUP过程会告知端口号,所以这里就不需要了

传输协议:RTP/AVP,表示RTP OVER UDP,如果是RTP/AVP/TCP,表示RTP OVER TCP

媒体格式:表示负载类型(payload type),一般使用96表示H.264

a=rtpmap:96 H264/90000

格式为a=rtpmap:<媒体格式><编码格式>/<时钟频率>

a=framerate:25

表示帧率

a=control:track0

表示这路视频流在这个会话中的编号
三、RTSP协议

rtp包由rtp头部和rtp荷载构成

1.rtp头部

RTP头部

​ 版本号(V):2Bit,用来标志使用RTP版本

​ 填充位§:1Bit,如果该位置位,则该RTP包的尾部就包含填充的附加字节

​ 扩展位(X):1Bit,如果该位置位,则该RTP包的固定头部后面就跟着一个扩展头部

​ CSRC技术器(CC):4Bit,含有固定头部后面跟着的CSRC的数据

​ 标记位(M):1Bit,该位的解释由配置文档来承担

​ 载荷类型(PT):7Bit,标识了RTP载荷的类型

​ 序列号(SN):16Bit,发送方在每发送完一个RTP包后就将该域的值增加1,可以由该域检测包的丢失及恢复

​ 包的序列。序列号的初始值是随机的

​ 时间戳:32比特,记录了该包中数据的第一个字节的采样时刻

​ 同步源标识符(SSRC):32比特,同步源就是RTP包源的来源。在同一个RTP会话中不能有两个相同的SSRC值

​ 贡献源列表(CSRC List):0-15项,每项32比特,这个不常用
2.rtp载荷

rtp载荷为音频或者视频数据

3.RTP OVER TCP

RTP默认是采用UDP发送的,格式为RTP头+RTP载荷,如果是使用TCP,那么需要在RTP头之前再加上四个字节

第一个字节:$,辨识符

第二个字节:通道,在SETUP的过程中获取

第三第四个字节: RTP包的大小,最多只能12位,第三个字节保存高4位,第四个字节保存低8位

四、H.264的RTP打包

1 H.264格式

H.264由一个一个的NALU组成,每个NALU之间使用00 00 00 0100 00 01分隔开

每个NALU的第一次字节都有特殊的含义,其内容如下

描述
bit[7] 必须为0
bit[5-6] 标记该NALU的重要性
bit[0-4]

2 H.264的RTP打包方式

H.264可以由三种RTP打包方式

  • 单NALU打包

    一个RTP包包含一个完整的NALU

  • 聚合打包

    对于较小的NALU,一个RTP包可包含多个完整的NALU

  • 分片打包

    对于较大的NALU,一个NALU可以分为多个RTP包发送

注意:这里要区分好概念,每一个RTP包都包含一个RTP头部和RTP荷载,这是固定的。而H.264发送数据可支持三种RTP打包方式

比较常用的是单NALU打包和分片打包,本文也只介绍这两种

单NALU打包
所谓单NALU打包就是将一整个NALU的数据放入RTP包的载荷中

这是最简单的一种方式,无需过多的讲解

分片打包
每个RTP包都有大小限制的,因为RTP一般都是使用UDP发送,UDP没有流量控制,所以要限制每一次发送的大小,所以如果一个NALU的太大,就需要分成多个RTP包发送,如何分成多个RTP包,下面来好好讲一讲

首先要明确,RTP包的格式是绝不会变的,永远多是RTP头+RTP载荷

 

RTP头部是固定的,那么只能在RTP载荷中去添加额外信息来说明这个RTP包是表示同一个NALU

如果是分片打包的话,那么在RTP载荷开始有两个字节的信息,然后再是NALU的内容

 

 

 第一个字节位FU Indicator,其格式如下

 

 

 

 

 

高三位:与NALU第一个字节的高三位相同

Type:28,表示该RTP包一个分片,为什么是28?因为H.264的规范中定义的,此外还有许多其他Type,这里不详讲

第二个字节位FU Header,其格式如下

 

 

S:标记该分片打包的第一个RTP包

E:比较该分片打包的最后一个RTP包

Type:NALU的Type

3 H.264 RTP包的时间戳计算
RTP包的时间戳起始值是随机的

RTP包的时间戳增量怎么计算?

假设时钟频率为90000,帧率为25

频率为90000表示一秒用90000点来表示

帧率为25,那么一帧就是1/25秒

所以一帧有90000*(1/25)=3600个点来表示

因此每一帧数据的时间增量为3600
4.H.264 RTP打包的sdp描述

dp描述着媒体信息,当使用vlc打开这个sdp文件后,会根据这些信息做相应的操作(创建套接字…),然后等待接收RTP包

这里给出RTP打包H.264的sdp文件,并描述每一行是什么意思

m=video 9832 RTP/AVP 96
a=rtpmap:96 H264/90000
a=framerate:25
c=IN IP4 127.0.0.1

这个一个媒体级的sdp描述,关于sdp文件描述详情可看从零开始写一个RTSP服务器(一)不一样的RTSP协议讲解

m=video 9832 RTP/AVP 96

格式为 m=<媒体类型> <端口号> <传输协议> <媒体格式 >
媒体类型:video,表示这是一个视频流

端口号:9832,表示UDP发送的目的端口为9832

传输协议:RTP/AVP,表示RTP OVER UDP,通过UDP发送RTP包

媒体格式:表示负载类型(payload type),一般使用96表示H.264

a=rtpmap:96 H264/90000

格式为a=rtpmap:<媒体格式><编码格式>/<时钟频率>

a=framerate:25

表示帧率

c=IN IP4 127.0.0.1

IN:表示internet

IP4:表示IPV4

127.0.0.1:表示UDP发送的目的地址为127.0.0.1
五、AAC的RTP打包

1 AAC格式

AAC音频文件有一帧一帧的ADTS帧组成,每个ADTS帧包含ADTS头部和AAC数据,如下所示

 

 ADTS头部的大小通常为7个字节,包含着这一帧数据的信息,内容如下


 

 

各字段的意思如下

syncword

总是0xFFF, 代表一个ADTS帧的开始, 用于同步.

ID

MPEG Version: 0 for MPEG-4,1 for MPEG-2

Layer

always: ‘00’

protection_absent

Warning, set to 1 if there is no CRC and 0 if there is CRC

profile

表示使用哪个级别的AAC,如01 Low Complexity(LC) – AAC LC

sampling_frequency_index

采样率的下标

 

 

aac_frame_length

一个ADTS帧的长度包括ADTS头和AAC原始流

adts_buffer_fullness

0x7FF 说明是码率可变的码流

number_of_raw_data_blocks_in_frame

表示ADTS帧中有number_of_raw_data_blocks_in_frame + 1个AAC原始帧
这里主要记住ADTS头部通常为7个字节,并且头部包含aac_frame_length,表示ADTS帧的大小

AAC的RTP打包方式
AAC的RTP打包方式并没有向H.264那样丰富,我知道的只有一种方式,原因主要是AAC一帧数据大小都是几百个字节,不会向H.264那么少则几个字节,多则几千

AAC的RTP打包方式就是将ADTS帧取出ADTS头部,取出AAC数据,每帧数据封装成一个RTP包

需要注意的是,并不是将AAC数据直接拷贝到RTP的载荷中。AAC封装成RTP包,在RTP载荷中的前四个字节是有特殊含义的,然后再是AAC数据,如下图所示

其中RTP载荷的一个字节为0x00,第二个字节为0x10

第三个字节和第四个字节保存AAC Data的大小,最多只能保存13bit,第三个字节保存数据大小的高八位,第四个字节的高5位保存数据大小的低5位

3 AAC RTP包的时间戳计算

假设音频的采样率位44100,即每秒钟采样44100次

AAC一般将1024次采样编码成一帧,所以一秒就有44100/1024=43帧

RTP包发送的每一帧数据的时间增量为44100/43=1025

每一帧数据的时间间隔为1000/43=23ms



posted @ 2022-04-26 15:35  泽良_小涛  阅读(1010)  评论(0编辑  收藏  举报