转自:http://blog.csdn.net/jychen105/article/details/47006345

一、什么是RTSP

通常所说的rtsp协议其实包含三个协议: rtsp协议, rtp协议, rtcp协议

各协议运作流程概要:

第一阶段:rtsp协议负责沟通传输什么数据,传的是图像还是声音,还是两者混合?图像的话传是h264流,还是h265流,还是jpeg流?后续的rtp,rtcp协议是采用tcp还是udp,端口号是多少都是通过第一阶段的rtsp协议确定的。

第二阶段:通过rtp协议传输数据,rtcp进行网络传输质量的监控

第三阶段:通过rtsp协议中断整个协议的传输

二、RTSP协议详解

rtsp协议是个文本协议,运行于tcp协议之上,服务器默认监听端口554,当然也可以修改成其他端口,一般不改。

协议包格式

  • 客户端协议格式

第一行:方法名:XXX\r\n

第二行:CSeq:XXX\r\n

第N行:XXX\r\n

\r\n

  • 服务器端协议格式

第一行:RTSP/1.0 XXX\r\n

第二行:CSeq:XXX\r\n

第N行:XXX\r\n

\r\n

协议最终都是以两个\r\n分隔

rtsp通信精简版

步骤 客户端 服务端 含义
1 请求OPTIONS 回应OPTIONS 查询服务器支持哪些命令或者方法
2 请求DESCRIBE 回应DESCRIBE 查询服务器发送流的描述信息
3 请求SETUP 回应SETUP 告诉服务器以TCP or UDP建立RTP,RTCP连接,并告诉端口号
4 请求PLAY 回应PLAY 告诉服务器可以用RTP协议发送数据过来了
最后一步 请求TEARDOWN 关闭连接 告诉服务器关闭连接

rtsp通信详细版本

客户端:192.168.1.109 
服务端:192.168.1.188

1. OPTIONS

客户端请求:

  1. OPTIONS rtsp://192.168.1.188/h264 RTSP/1.0
  2. CSeq: 2
  3. User-Agent: LibVLC/2.1.2 (LIVE555 Streaming Media v2013.12.05)

服务端回应:

  1. RTSP/1.0 200 OK
  2. CSeq: 2
  3. Date: Mon, Jul 21 2014 09:07:56 GMT
  4. Public: OPTIONS, DESCRIBE, SETUP, TEARDOWN, PLAY, PAUSE, GET_PARAMETER, SET_PARAMETER

需注意的点:

  • 回应的CSeq与请求的CSeq必须一致,后续rtsp命令下同。

  • PAUSE, GET_PARAMETER, SET_PARAMETER这几个命令可无,也就是一些命令服务器可以不实现。OPTIONS, SETUP, PLAY是一定要有的,其他的未认真调查。

2. DESCRIBE

客户端请求:

  1. DESCRIBE rtsp://192.168.1.188/h264 RTSP/1.0
  2. CSeq: 3
  3. User-Agent: LibVLC/2.1.2 (LIVE555 Streaming Media v2013.12.05)
  4. Accept: application/sdp

服务端回应:

  1. RTSP/1.0 200 OK
  2. CSeq: 3
  3. Date: Mon, Jul 21 2014 09:07:56 GMT
  4. Content-Base: rtsp://192.168.1.188/h264/
  5. Content-Type: application/sdp
  6. Content-Length: 547
  7. v=0
  8. o=- 1405932398518315 1 IN IP4 192.168.1.188
  9. s=Session streamed by "hua_an"
  10. i=h264
  11. t=0 0
  12. a=tool:LIVE555 Streaming Media v2012.10.24
  13. a=type:broadcast
  14. a=control:*
  15. a=range:npt=0-
  16. a=x-qt-text-nam:Session streamed by "hua_an"
  17. a=x-qt-text-inf:h264
  18. m=video 0 RTP/AVP 96
  19. c=IN IP4 0.0.0.0
  20. b=AS:500
  21. a=rtpmap:96 H264/90000
  22. a=fmtp:96 packetization-mode=1;profile-level-id=64002A;sprop-parameter-sets=J2QAKq2EBUViuKxUcQgKisVxWKjiECSFITk8nyfk/k/J8nm5s00IEkKQnJ5Pk/J/J+T5PNzZpsqAUAW6bIAAAfQAAGGocAAABbjYAAD0JBe91lA=,KP4Briw=
  23. a=control:track1

注意的点:

  • 服务端回应了两个协议,一个是rtsp的回应,还回应了一个sdp协议(Session Description Protocol),sdp协议最后一个只有一个\r\n。 rtsp协议是两个\r\n结尾。

  • sdp协议中描述了发送的流为h264,采样率为90000Hz (h264的采样率为90000HZ,因此时间戳的单位为1(秒)/90000,因此如果当前视频帧率为25fps,那时间戳间隔或者说增量应该为3600, 即每个naul单元的时间间隔为3600。此句话可以放在rtp协议封装h264时理解。)

  • sprop-parameter-sets为sps跟pps的base64编码组合。(sps,pps为h264 nalu单元的Sequence Parameter Sets (SPS) 和Picture Parameter Set (PPS), 后续会介绍)

3. SETUP

客户端请求:

  1. SETUP rtsp://192.168.1.188/h264/track1 RTSP/1.0
  2. CSeq: 4
  3. User-Agent: LibVLC/2.1.2 (LIVE555 Streaming Media v2013.12.05)
  4. Transport: RTP/AVP/TCP;unicast;interleaved=0-1

服务端回应:

  1. RTSP/1.0 200 OK
  2. CSeq: 4
  3. Date: Mon, Jul 21 2014 09:07:56 GMT
  4. Transport: RTP/AVP/TCP;unicast;destination=192.168.1.109;source=192.168.1.188;interleaved=0-1
  5. Session: 5C01EACE

此处为TCP建立RTP跟RTCP。RTP,RTCP都是利用此路连接,不再建立新连接,只是数据包格式不一样而以。 
注意interleaved=0-1, 0为传送RTP数据,1为RTCP数据

4. PLAY

客户端请求

  1. PLAY rtsp://192.168.1.188/h264/ RTSP/1.0
  2. CSeq: 5
  3. User-Agent: LibVLC/2.1.2 (LIVE555 Streaming Media v2013.12.05)
  4. Session: 5C01EACE
  5. Range: npt=0.000-

服务端回应

  1. RTSP/1.0 200 OK
  2. CSeq: 5
  3. Date: Mon, Jul 21 2014 09:07:56 GMT
  4. Range: npt=0.000-
  5. Session: 5C01EACE
  6. RTP-Info: url=rtsp://192.168.1.188/h264/track1;seq=28626;rtptime=98136845

播放,开始传输rtp数据。同时告知开始序号为28626, 开始时间戳为98136845

5. 最后一步

客户端请求:

  1. TEARDOWN rtsp://192.168.1.188/h264/ RTSP/1.0
  2. CSeq: 7
  3. User-Agent: LibVLC/2.1.2 (LIVE555 Streaming Media v2013.12.05)
  4. Session: 5C01EACE

服务端回应:

关闭RTSP连接

三、RTP协议

根据之前rtsp的协议,rtp即可以通过tcp,也可以通过udp传输。但是数据包协议格式是一样的。

  • tcp传输
协议格式 ‘$’ 0 长度(=RTP协议头长度+RTP数据长度) RTP协议头 RTP数据
长度信息 1字节 1字节 2字节 sizeof(RTP协议头) N
  • udp传输
协议格式 RTP协议头 RTP数据
长度信息 sizeof(RTP协议头) N

– 数据传输采用网络字节序

– RTP数据长度小于MTU长度, 一般是1500, 目的是为了网络传输避免分片,未深究如何避免分片的。

– 传输的流媒体数据就是封装在RTP数据部分

RTP协议头

  1. 0 1 2 3
  2. 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
  3. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  4. |V=2|P|X| CC |M| PT | sequence number |
  5. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  6. | timestamp |
  7. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  8. | synchronization source (SSRC) identifier |
  9. +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
  10. | contributing source (CSRC) identifiers |
  11. | .... |
  12. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  13. //set CC = 0, so there is no CSRC

转成c语言结构体(小端字节序):

  1. typedef struct
  2. {
  3. /* byte 0 */
  4. unsigned char csrc_len:4; /* CC expect 0 */
  5. unsigned char extension:1; /* X expect 1, see RTP_OP below */
  6. unsigned char padding:1; /* P expect 0 */
  7. unsigned char version:2; /* V expect 2 */
  8. /* byte 1 */
  9. unsigned char payload:7; /* PT RTP_PAYLOAD_RTSP */
  10. unsigned char marker:1; /* M expect 1 */
  11. /* byte 2,3 */
  12. unsigned short seq_no; /*sequence number*/
  13. /* byte 4-7 */
  14. unsigned long timestamp; /*time stamp*/
  15. /* byte 8-11 */
  16. unsigned long ssrc; /* stream number is used here. */
  17. } RTPHeader;/*12 bytes*/

四、RTCP

rtcp主要是用来解决网络流控的,如果是自实现rtsp服务器传输实时流,可以不实现此部分。

如果是实现rtsp客户端,建立实现一个Recvive Report包就行了,此包主要是报告丢包率,网络延迟是多少,方便服务器端调节。 
因为发的都是实时流,简单起见,recvive report封包时,丢包率为0,延迟也为0

五、h264是如何通过rtsp发送的

下篇

从零开始写一个发送h264的rtsp服务器(上)的更多相关文章

  1. 从零开始写一个发送h264的rtsp服务器(下)

    转自:http://blog.csdn.net/jychen105/article/details/47012099 一.H264是如何通过rtsp发送的 简单来说,H264就是通过打包到rtp协议的 ...

  2. 从零开始写一个Tomcat(贰)--建立动态服务器

    上文书说道如何通过http协议建立一个静态的服务器来访问静态网页,但我们选择tomcat最主要的原因还是因为它能动态的执行servlet,这边文章将引导你实现一个能够运行servlet的服务器,这个简 ...

  3. 从零开始写一个Tomcat(叁)--请求解析

    挖坑挖了这么长时间也该继续填坑了,上文书讲到从零开始写一个Tomcat(贰)--建立动态服务器,讲了如何让服务器解析请求,分离servlet请求和静态资源请求,读取静态资源文件输出或是通过URLCla ...

  4. 深入浅出React Native 3: 从零开始写一个Hello World

    这是深入浅出React Native的第三篇文章. 1. 环境配置 2. 我的第一个应用 将index.ios.js中的代码全部删掉,为什么要删掉呢?因为我们准备从零开始写一个应用~学习技术最好的方式 ...

  5. 用ASP.Net写一个发送ICQ信息的程序

    用ASP.Net写一个发送ICQ信息的程序 这里我给大家提供一个很实用的例子,就是在线发送ICQ信息.想一想我们在网页上直接给朋友发送ICQ信息,那是多么美妙的事情啊.呵呵,在吹牛啊,其实ICQ本来就 ...

  6. 从零开始写一个武侠冒险游戏-0-开发框架Codea简介

    从零开始写一个武侠冒险游戏-0-开发框架Codea简介 作者:FreeBlues 修订记录 2016.06.21 初稿完成. 2016.08.03 增加对 XCode 项目文件的说明. 概述 本游戏全 ...

  7. 2019-5-24-WPF-源代码-从零开始写一个-UI-框架

    title author date CreateTime categories WPF 源代码 从零开始写一个 UI 框架 lindexi 2019-05-24 15:54:36 +0800 2018 ...

  8. 从零开始写一个武侠冒险游戏-8-用GPU提升性能(3)

    从零开始写一个武侠冒险游戏-8-用GPU提升性能(3) ----解决因绘制雷达图导致的帧速下降问题 作者:FreeBlues 修订记录 2016.06.23 初稿完成. 2016.08.07 增加对 ...

  9. 从零开始写一个武侠冒险游戏-7-用GPU提升性能(2)

    从零开始写一个武侠冒险游戏-7-用GPU提升性能(2) ----把地图处理放在GPU上 作者:FreeBlues 修订记录 2016.06.21 初稿完成. 2016.08.06 增加对 XCode ...

随机推荐

  1. dede列表页调用

    {dede:list pagesize ='16'} <li class="item pull-left"> <a class="item-wrap&q ...

  2. JAVA 反射用法

    1.获得Class对象 Class<?>  classType  =  Class.forName() 可以通过传入一个全限定类名(包含包名)返回一个该类的Class类对象引用 . Cla ...

  3. java 添加自己的工具包

    一. 在添加工具包前环境变量要定位到当前目录, export CLASSPATH=.:/home/share/ 添加工具类 我的目录\\192.168.1.101\share\share\net\fe ...

  4. SqlServer中Sql查看存储过程

    ( 一)利用Sql语句查询数据库中的所有表 1.利用sysobjects系统表 select * from sysobjects where xtype='U'  2,利用sys.tables目录视图 ...

  5. fullcalendar插件日程管理

    日程管理-fullcalendar插件用法   前言 本文分享fullcalendar用法,最后面提供代码下载 说到日程管理,基于JQuery的插件FullCalendar当之无愧,完整的API稳定和 ...

  6. flume修改配置文件

    flume修改配置文件后,flume进程会自动将配置文件更新至服务中,同时会初始化日志,重新对于metrics进行记录的. 所以拿api做监控的同学要注意这点啦

  7. 009 jquery过滤选择器-----------(表单对象属性过滤选择器 与 表单选择器)

    1.表单对象属性选择器 2.程序 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"& ...

  8. 按行拆分文本文件与合并文本文件---I/O流---java

    背景 在进行自然语言处理的中文词性标注时   进行测试时由于测试数据文本行数较多  而且测试每次标注一行的用时稍长 如果一次将文件读进来测试机器运行时间要连续不能中断  而且 只能一台机器进行工作 于 ...

  9. springmvc+swagger2

    一.swagger2依赖 <!--swagger--> <dependency> <groupId>io.springfox</groupId> < ...

  10. android listView 点两下才监听到

    因为 对应的控件设置了 android:focusableInTouchMode="true" 意思是 触摸模式下 点击第一次 是 获得焦点.===