流媒体传输协议系列之--RTSP协议详解


1. RTSP连接的建立过程

      RTSPServer类用于构建一个RTSP服务器,该类同时在其内部定义了一个RTSPClientSession类,用于处理单独的客户会话。

      首先创建RTSP服务器(具体实现类是DynamicRTSPServer),在创建过程中,先建立Socket(ourSocket)在TCP的554端口进行监听,然后把连接处理函数句柄(RTSPServer::incomingConnectionHandler)和socket句柄传给任务调度器(taskScheduler)。

      任务调度器把socket句柄放入后面select调用中用到的socket句柄集(fReadSet)中,同时将socket句柄和incomingConnectionHandler句柄关联起来。接着,主程序开始进入任务调度器的主循环(doEventLoop),在主循环中调用系统函数select阻塞,等待网络连接。

      当RTSP客户端输入(rtsp://192.168.0.1/1.mpg)连接服务器时,select返回对应的socket,进而根据前面保存的对应关系,可找到对应处理函数句柄,这里就是前面提到的incomingConnectionHandler了。在incomingConnectionHandler中创建了RTSPClientSession,开始对这个客户端的会话进行处理。

 

 

 


2. DESCRIBE请求消息处理过程

      RTSP服务器收到客户端的DESCRIBE请求后,根据请求URL(rtsp://192.168.0.1/1.mpg),找到对应的流媒体资源,返回响应消息。live555中的ServerMediaSession类用来处理会话中描述,它包含多个(音频或视频)的子会话描述(ServerMediaSubsession)。

      RTSP服务器收到客户端的连接请求,建立了RTSPClientSession类,处理单独的客户会话。在建立RTSPClientSession的过程中,将新建立的socket句柄(clientSocket)和RTSP请求处理函数句柄RTSPClientSession::incomingRequestHandler传给任务调度器,由任务调度器对两者进行一对一关联

      当客户端发出RTSP请求后,服务器主循环中的select调用返回,根据socket句柄找到对应的incomingRequestHandler,开始消息处理。先进行消息的解析,如果发现请求是DESCRIBE则进入handleCmd_DESCRIBE函数。根据客户端请求URL的后缀(如1.mpg),调用成员函数DynamicRTSPServer::lookupServerMediaSession查找对应的流媒体信息ServerMediaSession。如果ServerMediaSession不存在,但是本地存在1.mpg文件,则创建一个新的ServerMediaSession。在创建ServerMediaSession过程中,根据文件后缀.mpg,创建媒体MPEG-1or2的解复用器(MPEG1or2FileServerDemux)。再由MPEG1or2FileServerDemux创建一个子会话描述MPEG1or2DemuxedServerMediaSubsession。最后由ServerMediaSession完成组装响应消息中的SDP信息(SDP组装过程见下面的描述),然后将响应消息发给客户端,完成一次消息交互。

 

SDP消息组装过程:

 

      ServerMediaSession负责产生会话公共描述信息,子会话描述由MPEG1or2DemuxedServerMediaSubsession产生。 MPEG1or2DemuxedServerMediaSubsession在其父类成员函数OnDemandServerMediaSubsession::sdpLines()中生成会话描述信息。在sdpLines()实现里面,创建一个虚构(dummy)的FramedSource(具体实现类为MPEG1or2AudioStreamFramer和MPEG1or2VideoStreamFramer)和RTPSink(具体实现类为MPEG1or2AudioRTPSink和MPEG1or2VideoRTPSink),最后调用setSDPLinesFromRTPSink(...)成员函数生成子会话描述。

 

Live555库是一个使用开放标准协议如RTP/RTCP、RTSP、SIP等实现多媒体流式传输的开源C 库集。这些函数库可以在Unix、Windows、QNX等操作系统下编译使用,基于此建立RTSP/SIP服务器和客户端来实现多媒体流的传输。下面给出具体实现过程[4]

(1)客户端发起RTSP OPTION请求,目的是得到服务器提供什么方法。RTSP提供的方法一般包括OPTIONS、DESCRIBE、SETUP、TEARDOWN、PLAY、PAUSE、SCALE、GET_PARAMETER。

(2)服务器对RTSP OPTION回应,服务器实现什么方法就回应哪些方法。在此系统中,我们只对DESCRIBE、SETUP、TEARDOWN、PLAY、PAUSE方法做了实现。

(3)客户端发起RTSP DESCRIBE请求,服务器收到的信息主要有媒体的名字,解码类型,视频分辨率等描述,目的是为了从服务器那里得到会话描述信息(SDP)。

(4)服务器对RTSP DESCRIBE响应,发送必要的媒体参数,在传输H.264文件时,主要包括SPS/PPS、媒体名、传输协议等信息。

(5)客户端发起RTSP SETUP请求,目的是请求会话建立并准备传输。请求信息主要包括传输协议和客户端端口号。

(6)服务器对RTSP SETUP响应,发出相应服务器端的端口号和会话标识符。

(7)客户端发出了RTSP PLAY的请求,目的是请求播放视频流。

(8)服务器对RTSP PLAY响应,响应的消息包括会话标识符,RTP包的序列号,时间戳。此时服务器对H264视频流封装打包进行传输。

(9)客户端发出RTSP TEARDOWN请求,目的是关闭连接,终止传输。

(10)服务器关闭连接,停止传输。

 


3. SETUP请求消息处理过程

        RTSPClientSession类用于处理单独的客户会话。其类成员函数handleCmd_SETUP()处理客户端的SETUP请求。调用parseTransportHeader()对SETUP请求的传输头解析,调用子会话(这里具体实现类为OnDemandServerMediaSubsession)的getStreamParameters()函数获取流媒体发送传输参数。将这些参数组装成响应消息,返回给客户端。

        获取发送传输参数的过程:调用子会话(具体实现类MPEG1or2DemuxedServerMediaSubsession)的createNewStreamSource(...)创建MPEG1or2VideoStreamFramer,选择发送传输参数,并调用子会话的createNewRTPSink(...)创建MPEG1or2VideoRTPSink。同时将这些信息保存在StreamState类对象中,用于记录流的状态。

        客户端发送两个SETUP请求,分别用于建立音频和视频的RTP接收。

4. PLAY请求消息处理过程

      RTSPClientSession类成员函数handleCmd_PLAY()处理客户端的播放请求。首先调用子会话的startStream(),内部调用MediaSink::startPlaying(...),然后是MultiFramedRTPSink::continuePlaying(),接着调用MultiFramedRTPSink::buildAndSendPacket(...)。buildAndSendPacke内部先设置RTP包头,内部再调用MultiFramedRTPSink::packFrame()填充编码帧数据。

      packFrame内部通过FramedSource::getNextFrame(), 接着MPEGVideoStreamFramer::doGetNextFrame(),再接着经过MPEGVideoStreamFramer::continueReadProcessing(), FramedSource::afterGetting(...), MultiFramedRTPSink::afterGettingFrame(...), MultiFramedRTPSink::afterGettingFrame1(...)等一系列繁琐调用,最后到了MultiFramedRTPSink::sendPacketIfNecessary(), 这里才真正发送RTP数据包。然后是计算下一个数据包发送时间,把MultiFramedRTPSink::sendNext(...)函数句柄传给任务调度器,作为一个延时事件调度。在主循环中,当MultiFramedRTPSink::sendNext()被调度时,又开始调用MultiFramedRTPSink::buildAndSendPacket(...)开始新的发送数据过程,这样客户端可以源源不断的收到服务器传来的RTP包了。

发送RTP数据包的间隔计算方法:

        Update the time at which the next packet should be sent, based on the duration of the frame that we just packed into it.


http://blog.sina.com.cn/s/blog_450e44880100mfiu.html


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

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

相关文章

身份证明检索失败,如何解决?

今天遇到一个很奇怪的问题2台几乎完全一样的机器,连同一台ORACLE服务器,可是一台机上测试成功,另一台机器测试失败,神奇!上网搜索了资料后发现问题,解决方法如下,本人已经实践证明下面的方法确实…

纠结

几年前,我一同事回家创业,当时我们一起做软件开发,他觉得上班没意思,就决定回老家创业,当时他创业的项目是零售项目,离职回去筹备了几个月,跟我们看到的创业老板一样,当时他也去挖了…

管理系统中计算机应用第二章,管理系统中计算机应用第二章.doc

管理系统中计算机应用第二章.doc第二章 企业管理的信息化平台一、单项选择题(本大题共30小题,每小题1分,共30分)1.从理论上分析,传统的IP地址(IPv4)最多可以访问的用户数是( )A.255*255*255*255   B.8*8*8*8   C.32*32*32*32   D.256*2…

更新了一个新版本的editplus 语法文件(for nagios)

从editplus上下载的nagios 语法文件,发现不支持nrpe.cfg 很多参数也没有 在它上面更新了一下,版权是原作者的 转载于:https://blog.51cto.com/yahoon/743633

RTSP的报文结构

RTSP的报文结构 RTSP是一种基于文本的协议,用CRLF作为一行的结束符。使用基于文本协议的好处在于我们可以随时在使用过程中的增加自定义的参数,也可以随便将协议包抓住很直观的进行分析。 RTSP有两类报文:请求报文和响应报文。请求报文是指从…

Qt性能优化,一位资深Qt工程师的经验

Qt是一个1991年由Qt Company开发的跨平台C图形用户界面应用程序开发框架。它既可以开发GUI程序,也可用于开发非GUI程序,比如控制台工具和服务器。Qt 支持的操作系统有很多,例如通用操作系统 Windows、Linux、Unix,智嵌入式系统 QN…

[引]生成加密和解密的密钥

1.对称密钥2.不对称密钥3.将非对称密钥存储在密钥容器中4.将非对称密钥存储在密钥容器中示例 创建和管理密钥是加密过程的一个重要部分。对称算法要求创建必须对不应解密数据的任何人保密的密钥和初始化向量 (IV)。不对称算法要求创建一个公钥和一个私钥。公钥可以对任何人公开…

centos7装单机hadoop2.7.3

(1)hadoop2.7.3下载(前提:先安装java环境)下载地址:http://hadoop.apache.org/releases.html(注意是binary文件,source那个是源码)(2)解压tar.gz (3&#xff…

计算机指令称,通俗解释什么叫计算机指令?

实际上能接触到“计算机指令”的人,只是少数电脑工程师。现在一般的电脑程序员都已经无需使用计算机指令了,因为他们编程序已经使用高级的计算机语言了。下面我尽量用通俗的语言来试着解释。计算机由CPU、内存、硬盘、显示器和键盘等部件组成。计算机软件…

JAVA_Thread_deadlock

package com.kk.thread;/* * 本类演示死锁的形成 * 基本数据类型是不能作为同步块的参考,例:int b;synchronized(b)*/public class TicketsSystem {public static void main(String[] args)throws Exception { SellThread sellnew SellThread();new Thread(sell).start(…

STM32和Arduino对比,谁更厉害?

前两天有一个同学问我嵌入式的学习路线他是一个大三的学生,我看了他的简历,里面几乎没什么项目经验,对于企业来说这样的学生就好比一张白纸一样,当然,这样的学生很难拿到一份好的offer。学习路线的文章我记得已经发了很…

窗体中实现按 回车键 跳到下一个可选的TabIndex控件

Form中一“textbox”,两“button”,如何实现在textbox中按下回车响应button.click事件 :1)把按钮的tabindex依次设置.如btnSure 1 ,btnModify 2, textbox 5等// 把下面的代码放到窗体中可以实现按回车键跳到下一个可选的TabIndex控件:protec…

技术支持

iOS技术支持 有问题的可以留言。 邮箱地址:838086119qq.com 地址:上海市复旦软件园 谢谢! iOS program design & system consultation if you have any question, please contact me with no hesitate Email: 838086119qq.com Add: 2B05 of Fudan So…

人大计算机在职考研好考吗,人大在职研究生好考吗?通过率高吗?

答:最近咨询人大在职研究生进行学习的人非常多,其中咨询最多的问题是考试难度及通过率。下面就通过在职研究生招生信息网为大家介绍一下,人大在职研究生好考吗?通过率高吗?人大在职研究生招生是采用同等学力申硕的方式,该方式是…

可能你还不懂浮点数

在网上看到一个问题然后看到这篇关于浮点数的文章,希望大家看了之后有所启发想一下,为什么第一个打印的和预设值不同,但是第二个是相同的?如图:尾数部分是如何转变成二进制的?前言很多人在初学写程式时都会…

股票自动交易使用协议

国家的法律规定其它人是不可能代替别人进行股票操作的。所以我们让用户使用股票自动交易软件的时候必须很清楚的让用户知道,他使用这个软件是他自己的意图,软件执行的策略也是它自己的策略,而不是我强加给他的。这样我们就需要写一个协议给用…

RTP协议的封装

最近一段时间学习了RTP协议相关的内容,一方面为了将自己学到的部分记录下来,便于后续查找,另一方面用于记录笔记 一个协议的封装是为了满足协议的功能需求的。从前面提出的功能需求,可以推测出RTP封装中应该有同步源和时戳等字段&…

【收集】ADOADO.NET 读取 Oracle 数据集

开始尝试用存储过程读取Oracle 数据集,收集了一些文章,基本上都来自MSDN:使用 ADO.NET 访问 Oracle 9i 存储过程 http://www.microsoft.com/china/MSDN/library/data/dataAccess/DMSDNorsps.mspx?mfrtrue如果包返回多个游标,则 D…

python 运行shell命令

在python 中实现运行多条shell命令 今天小编就为大家分享一篇在python 中实现运行多条shell命令,具有很好的参考价值,希望对大家有所帮助。 一起跟随小编过来看看吧 使用py时可能需要连续运行多条shell 命令 # coding: UTF-8 import sys reload(sys) sy…

组合公式计算机,(最新整理)排列与组合的概念与计算公式

《(最新整理)排列与组合的概念与计算公式》由会员分享,可在线阅读,更多相关《(最新整理)排列与组合的概念与计算公式(3页珍藏版)》请在人人文库网上搜索。1、完整)排列与组合的概念与计算公式(完整)排列与组合的概念与计算公式编辑整理:尊敬的…