概述
RTSP(Real Time Streaming Protocol),参考标准为 RFC2326,RTSP 协议是基于文本的实时流传输协议,是 TCP/一个应用层协议。1.RTSP 在体系结构上位于 RTP 和 RTCP 之上,其使用 TCP 或 UDP 完成数据传输。
2.相比HTTP,请求由客户机发出,服务器作出响应。
RTSP是客户机和服务器都可以,RTSP可以是双向的。
3.RTSP 协议默认端口:554,默认承载协议为 TCP。
4.从控制逻辑上来说 RTSP 和 FTP 相似,流控和数据流是分开的。


RTSP协议架构:

jetson python rtsp推流硬件编码 rtsp推流原理_服务器


RTSP 消息格式

1.请求格式(Request)

jetson python rtsp推流硬件编码 rtsp推流原理_服务器_02


2.回应消息格式(Response)

jetson python rtsp推流硬件编码 rtsp推流原理_客户端_03


3、RTSP 中的 C(Client)与 S(Server)交互流程图解:

jetson python rtsp推流硬件编码 rtsp推流原理_码流_04


4、RTSP 关键字段说明

4.1 关键字:OPTIONS

得到服务器提供的可用方法(OPTION、DESCRIBE、SETUP、TEARDOWN、PLAY、PAUSE、SCALE、

GET_PARAMETER、SET_PARAMETER)。

4.2 关键字:DESCRIBE

请求流的 SDP 信息。客户端向服务器请求媒体资源描述,服务器端通过SDP(Session Description Protocol)格式回应客户端的请求。资源描述中会列出所请求媒体的媒体流及其相关信息,典型情况下,音频和视频分别作为一个媒体流传输

注解:此处需要了解 H264 Law Data 如何生成 SPS PPS 信息。

4.3 关键字:SETUP

客户端提醒服务器建立会话,并建立传输模式。SETUP请求确定了具体的媒体流如何传输,该请求必须在PLAY请求之前发送。SETUP请求包含媒体流的URL和客户端用于接收RTP数据(audio or video)的端口以及接收RTCP数据(meta information)的端口。服务器端的回复通常包含客户端请求参数的确认,并会补充缺失的部分,比如服务器选择的发送端口。每一个媒体流在发送PLAY请求之前,都要首先通过SETUP请求来进行相应的配置。

4.4 关键字:PLAY

客户端发送播放请求。客户端通过PLAY请求来播放一个或全部媒体流,PLAY请求可以发送一次或多次,发送一次时,URL为包含所有媒体流的地址,发送多次时,每一次请求携带的URL只包含一个相应的媒体流。PLAY请求中可指定播放的range,若未指定,则从媒体流的开始播放到结束,如果媒体流在播放过程中被暂停,则可在暂停处重新启动流的播放。

注解:此处引入 RTP 协议及 RTCP 协议。

4.5关键字:PAUSE

播放暂停请求。

注解:此关键字经常用在录像回放当中,实时视频流几乎用不到。

4.6 关键字:TEARDOWN

客户端发送关闭请求

4.7 关键字:GET_PARAMETER

从服务器获取参数,目前主要获取时间参数(可扩展)

4.8 关键字:SET_PARAMETER

给指定的 URL 或者流设置参数(可扩展)

5.RTP 协议概述

RTP 全名是 Real-time Transport Protocol(实时传输协议)。它是 IETF 提出的一个标准,对应的 RFC 文档为 RFC3550 (RFC1889 为其过期版本) 。 RFC3550 不仅定义了 RTP, 而且定义了配套的相关协议 RTCP (Real-timeTransport Control Protocol,即实时传输控制协议)。RTP 用来为 IP 网上的语音、图像、传真等多种需要实时传输的多媒体数据提供端到端的实时传输服务。RTP 为 Internet 上端到端的实时传输提供时间信息和流同步,但并不保证服务质量,服务质量由 RTCP 来提供。RTP 用于在单播或多播网络中传送实时数据


以上部分内容来源于网络,如有侵权,请联系作者删除,谢谢!


ScheduleInit 这个函数到时候来发送数据的
SAMPLE_VENC_1080P_CLASSIC:这里面把H264的数据塞到buff里面去
EventLoop:这里轮训等待client来连接自己


总结:关于rtsp的处理其实很复杂,我们最方便的就是去移植别人的代码过来用


源码分析:
rtsp分析:
1.ringmalloc(1280*720); 这个里面分配了32个buff,每个buff都是 1280 x 720字节大小的
所以分配的内存大小就是 1280 x 720 x 32 / 1024 / 1024 = 28MBytes
2.PrefsInit 设置rtsp协议的port为554,主机名和域名
3.signal(SIGINT, IntHandl); 绑定signal interrupt信号,对应的是ctrl+c
4.tcp_listen
<1>创建socket
<2>setsockopt设置socket的ip和端口号可复用, 并且bind
<3>ioctl把socket设置为非阻塞方式
<4>listen
5.ScheduleInit
<1>创建新的线程 schedule_do
6.schedule_do
<1>检测多个rtp_session中是否有数据要发送的,如果有就调用 sched[i].play_action
去发送,play_action是一个函数指针,具体在哪里定义,后面看
<2>do while 内部的内容,每33333ns去执行一次
7.RTP_port_pool_init 定义rtp的端口号
8.SAMPLE_VENC_1080P_CLASSIC 这个是编码的,基本上都是hisi提供的,有部分地方需要修改
后面讨论
9.EventLoop 这个函数每隔2s去socket的连接队列里面去取一个socket,使用accept去取,
因为ioctl把socket设置为非阻塞方式,所以accpet取不到fd就会返回错误
<1>如果有新的client连接,就AddClient增加一个新的客户端,并且调用RTSP_initserver
去进行初始化
<2>ScheduleConnections 对已有的连接进行调度
10.继续讨论这个SAMPLE_VENC_1080P_CLASSIC
SAMPLE_VENC_1080P_CLASSIC
SAMPLE_COMM_VENC_StartGetStream
SAMPLE_COMM_VENC_GetVencStreamProc
HisiPutH264DataToBuffer
<1>计算一帧码流(其中有多个包),所有的包的有效长度所占的字节数
<2>把每个包的有效字节都拷到ringbuff里面去
<3>计算出sps pps信息
<4>添加到ringbuff中去等待发送
11.有client连接之后
EventLoop
ScheduleConnections
RtspServer
RTSP_handler
RTSP_state_machine 这里进行rtsp OPTIONS、DESCRIBE、SETUP、PLAY等信息的
交换
12.SETUP的过程中就要去建立UDP的socket

typedef struct hiVENC_STREAM_S
{
    VENC_PACK_S *pstPack;   帧码流包结构
    HI_U32      u32PackCount;   一帧码流的所有包的个数
    HI_U32      u32Seq;     码流序列号, 按帧获取帧序号;按包获取包序号

    union  码流特征信息
    {
        VENC_STREAM_INFO_H264_S  stH264Info;         /*the stream info of h264*/
        VENC_STREAM_INFO_JPEG_S  stJpegInfo;         /*the stream info of jpeg*/
        VENC_STREAM_INFO_MPEG4_S stMpeg4Info;       /*the stream info of mpeg4*/
        VENC_STREAM_INFO_H265_S  stH265Info;        /*the stream info of h265*/
    };
}VENC_STREAM_S;			
			
typedef struct hiVENC_PACK_S
{
    HI_U32   u32PhyAddr;      码流包物理地址                  
    HI_U8   *pu8Addr;         码流包首地址                  
    HI_U32   u32Len;          码流包长度                  
    
    HI_U64   u64PTS;          时间戳。单位: us。                     
    HI_BOOL  bFrameEnd;       帧结束标识                     
    
    VENC_DATA_TYPE_U  DataType;码流类型,支持 H.264/JPEG/MPEG-4 协议类型的数据包                   
    HI_U32   u32Offset;   码流包中有效数据与码流包首地址 pu8Addr 的偏移

	HI_U32 u32DataNum;   当前码流包数据中包含其他类型码流包的个数
	VENC_PACK_INFO_S stPackInfo[8];
}VENC_PACK_S

以上部分内容来源于网络,如有侵权,请联系作者删除,谢谢!