一个RtspServer的设计与实现和RTSP2.0简介

  前段时间着手实现了一个RTSP Server,能够正常实现多路RTSP流的直播播放,因项目需要,只做了对H.264和AAC编码的支持,但是相信其他编码的实现基本逻辑也是想通的。这里我把主要设计和思考过程,以及实现框架分享一下。因为关注的是直播,这里只讨论RTSP直播协议。

RTSP协议概述与RTSP2.0

  众所周知,RTSP协议是一个流媒体协议,可以实现直播和点播形式的音频与视频流的播放。RTSP协议定义了多种服务器-客户端之间交互的接口,主要有OPTIONS,DESCRIBE,SETUP,PLAY,TEARDOWN,RECORD,ANNOUNCE。网络上已经有很多针对RTSP协议的文章,我这里不准备进行过多介绍,详细的协议定义,可以参见RFC2326。RTSP并不包括具体数据的传输,该功能一般由RTP与RTCP协议来实现,并可以通过TCP或UDP两种底层传输方式进行。

  下图是典型的RTSP直播过程中服务端-客户端主要交互过程:

  当然,直播过程中也可能在服务器与客户端之间调用GET_PARAMETER等其他接口,上图偷懒省略了。上图绿色部分表示的是数据传输。之前说过,流媒体数据传输不是RTSP协议的内容,由RTP包来做。但是具体在实现上,RTP包可以通过UDP或TCP的方式来进行,而且这两种传输方式,区别其实还不小,下面具体说下。

RTSP 数据传输流程

1. RTSP over UDP

  对于udp模式,客户端在发送PLAY以后,就开始建立udp端口,以接收服务器发来的RTP包,同样,服务器也会建立udp端口,并向客户端发送RTP包。这是网上大部分程序所采用的方式,优点是逻辑清晰,实现方便,不过缺点也很明显,就是udp所固有的,容易丢包,尤其是在高分辨率高码率下。

  

2. RTSP over TCP

  对tcp模式,通过SETUP接口来指定传输方式,服务器返回同样数据以确定双方通过tcp方式来传输数据。不过跟udp最大的不同是,rtsp over tcp的形式,不再创建单独的tcp通道,而是直接使用之前rtsp通信所使用的tcp通道,流程如下所示:

  

  由于跟rtsp消息使用同一个tcp端口,为了区分,rtp以及rtcp包,增加了4个字节额外的字段,并通过特殊的标识'$',与正常的rtsp消息进行了区分。

RTSP Live Server 设计与实现

1. 程序框架

  我这次所实现的RTSP Server,主要功能是采集摄像头和麦克风数据,进行h.264编码以及aac编码,并对外提供RTSP直播流服务。我在实际写代码中,也是首先实现了rtsp over udp的模式,然而,通过实际测试,我发现在高分辨率高码率情况下,由于h.264 NAL单元过大,会拆分成很多的rtp包,而udp不可靠的传输方式,总是难免丢包,在低码率的时候还不明显,高码率情况下,丢包导致的花屏会频繁出现,这样体验特别差。于是我重新实现了一份rtsp over tcp模式的代码,顺利解决了这个问题。

  

2. 关于h264在sdp中的描述

  h264在sdp中的媒体信息,大多都是可以直接填写的,但是有两项数据需要根据编码后的数据来提取,就是profile-level-id和sprop-parameter-sets。这两项字符串数据的计算公式

  • profile-level-id = "Base16(sps[1])" + "Base16(sps[2])" + "Base16(sps[3])"
  • sprop-parameter-sets = "Base64(sps)" + "," + "Base64(pps)"

3. 主要代码

3.1 Rtsp服务接口

3.2 RtspSession在TCP通道里处理RTSP消息与RTP报文

4. 运行效果

  同时用vlc和ffplay进行多路播放,以tcp请求的方式,效果如下,延迟极低。

关于RTSP 2.0

  2016年IETF发布了新的RTSP标准,这就是就是RTSP2.0协议(RFC7826),新标准还是有不少修改的,除了完善一些原协议的中的定义,还有一些我觉得比较重要的是,对接口method进行了修改,比如删除了RECORDANNOUNCE方法,新增了PLAY_NOTIFY方法。

  • 删除了RECORD,这表示你不能再通过这个接口来控制服务器进行数据的录制了,可以选择在PLAY方法中,添加一些参数,来实现服务器对直播数据进行录制,还可以分隔录制。
  • 删除了ANNOUNCE,这意味着,不能像RTMP一样,客户端通过向服务器推送数据,来实现本机数据对外直播了,这可能需要其他的推送途径来进行替代了。
  • 至于PLAY_NOTIFY,它替代来原来Server向Client端发送ANNOUNCE方法,所实现的功能,也就是告诉客户端,需要根据新参数来调整直播播放状态。
  • 删除通过UDP传输RTSP消息的形式
  • 删除通过发PLAY消息来keep alive的方式(用SET_PARAMETER来做)
  • RTSP Server也可向Client发TEARDOWN消息
  • 支持IPV6
  • RTSP请求,支持pipelining的形式,也就是聚合Request。比如可以不等服务器返回,把SETUP和PLAY一起发送,这样可以提高至少一个RTT的启动时间。当然需要在消息里加上相关字段。
  • 重写了状态机,完善了服务器对客户端来说在各个状态之间的转换和行为
  • RTSP消息内支持URI了
  • 扩展了REDIRECT方法,等,等等。

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

haibindev.cnblogs.com,合作请联系QQ。(转载请注明作者和出处~)

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

一个RtspServer的设计与实现和RTSP2.0简介的更多相关文章

  1. .Net开发笔记(十九) 创建一个可以可视化设计的对象

    阅读本篇博客之前需要了解VS窗体设计器的工作原理,详细可参见本系列博客(十).(十一).(十二).必须需要知道的一条结论就是:处于窗体设计器(Form Designer)中的任何组件(包含控件,下同) ...

  2. Swing 是一个为Java设计的GUI工具包

    Swing 是一个为Java设计的GUI工具包. Swing是JAVA基础类的一部分. Swing包括了图形用户界面(GUI)器件如:文本框,按钮,分隔窗格和表. Swing提供许多比AWT更好的屏幕 ...

  3. App 图标设计 - 圆角透明效果(0 基础使用 PS)

    App 图标设计 - 圆角透明效果(0 基础使用 PS) 方法: 如果你有些基础,就不必看图文教程了: 1.使用圆角矩形工具选中,设置圆角尺寸[例如:1024*1024 px(圆角:160 px)] ...

  4. CS5263替代PS176|设计DP1.4转HDMI2.0音视频转换线方案|PS176方案

    PS176是一个显示端口 (DP)至HDMI 2.0视频接口转换器适用于需要视频协议转换的电缆适配器.电视接收器.监视器和其他应用.它将接受任何显示端口输入格式,包括DP 1.1a.dp1.2a.dp ...

  5. 庆祝下,提交了第一个ceph pull request。实现了从0到1的突破

    庆祝一下!经过社区老司机的带路,昨天提交了第一个ceph pull request.实现了从0到1的突破,希望再接再厉提交更多代码到社区,为社区发展贡献一点自己力量. 提交的第一个被社区fix的bug ...

  6. JavaScript语言里判断一个整数,属于哪个范围:大于0;小于0;等于0

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  7. 如何提交代码到CEPH Repo。 顺便庆祝下,提交了第一个ceph pull request。实现了从0到1的突破

    庆祝一下!经过社区老司机的带路,昨天提交了第一个ceph pull request.实现了从0到1的突破,希望再接再厉提交更多代码到社区,为社区发展贡献一点自己力量. 提交的第一个被社区fix的bug ...

  8. 公司新来了一个质量工程师,说团队要保证 0 error,0 warning

    摘要:静态代码检查又称为静态程序分析,是指在不运行计算机程序的条件下,进行程序分析的方法. 本文分享自华为云社区<公司新来了一个质量工程师,说团队要保证 0 error,0 warning> ...

  9. 优化一个奇葩表设计上的全表扫描SQL

    之前在一个比较繁忙的系统抓到的耗时长.消耗CPU多的一条SQL,如下:SELECT * FROM Z_VISU_DATA_ALARM_LOG TWHERE TO_DATE(T.T_TIMESTR, ' ...

随机推荐

  1. visio流程图软件

    microsoft visio 2013 64位 链接:http://pan.baidu.com/s/1bnjWa1T 密码:9ylc 标准图表 使用现有的数据,您可以生成许多种类的 Visio 标准 ...

  2. Linux中创建Daemon进程的三种方法

    什么是daemon进程? Unix/Linux中的daemon进程类似于Windows中的后台服务进程,一直在后台运行运行,例如http服务进程nginx,ssh服务进程sshd等.注意,其英文拼写为 ...

  3. Python练习----购物车

    要求: 1.启动程序后,输入用户名密码后,如果是第一次登录,让用户输入工资,然后打印商品列表 2.允许用户根据商品编号购买商品 3.用户选择商品后,检测余额是否够,够就直接扣款,不够就提醒 4.可随时 ...

  4. Linux入门(2)——Ubuntu16.04安装wineQQ

    http://www.ubuntukylin.com/application/show.php?lang=cn&id=279 下载得到wine-qqintl.zip 解压得到wine-qqin ...

  5. [SVN服务器搭建] 在myecplise下使用的 tortoise1.9 64位 跟 subversion1.9的服务器使用

    由于在公司经常用到SVN服务器,所以自己也想搭建在本机上面搭建一个SVN服务器玩玩,废话不多说,下面直接贴出来如何搭建的.  一.tortoise1.9 64位下载 直接百度下载即可,百度时候需要显示 ...

  6. java对象类型转换和多态性

    html { font-family: sans-serif } body { margin: 0 } article,aside,details,figcaption,figure,footer,h ...

  7. 使用sklearn进行数据挖掘-房价预测(4)—数据预处理

    在使用机器算法之前,我们先把数据做下预处理,先把特征和标签拆分出来 housing = strat_train_set.drop("median_house_value",axis ...

  8. 一个强大的封装好的pdo处理类

    php5.5后就不支持mysql扩展了,也就是说这以后都不能使用msyql_conncet之类的函数了.不过没有关系,pdo比mysql有更多优势,写法也很简单,下面贴出一个来自互联网的pdo处理类. ...

  9. 路由知识 静态路由 rip eigrp ospf

    第1章 路由选择原理 1.1 几个概念 1.1.1 被动路由协议 用来在路由之间传递用户信息 1.1.2 主动路由协议 用于维护路由器的路由表 R2#show ip route Codes: C - ...

  10. 第三章 CUDA设备相关

    这章介绍了与CUDA设备相关的参数,并给出了了若干用于查询参数的函数. 章节代码(已合并): #include <stdio.h> #include "cuda_runtime. ...