【Darwin学习笔记】之RTSPSession

今天详细的看了下RTSPSession的会话处理代码,该模块主要是Run方法内对会话的状态机进行管理,实现对RTSP会话的处理,我以点播Movie文件夹下的视频文件为例,深入的学习了(Describe、Setup、Play的点播流程),并按照状态机的处理顺序对他们进行一一解析,如下:

【转载请注明出处】:http://blog.csdn.net/longlong530

1. 状态机 kReadingFirstRequest

通过fInputStream.ReadRequest()调用Session绑定的socket,获取数据,该函数有两个返回码:

a) QTSS_NoErr,意味着已经收到该socket的完整数据,但是没有收集到本次请求的全部数据,这时需要接着请求监听读事件,获取更多数据组成完整的RTSP请求消息。

b) QTSS_RequestArrived,意味着此时已经收到完整请求的报文,可以正常进入下一状态机了。

c) E2BIG,表示缓存区已经溢出,默认缓存区的大小为( kRequestBufferSizeInBytes = 4096),进入kHaveNonTunnelMessage状态机,然后在改状态机下响应错误

// Check for an overfilled buffer, and return an error.
  if (err == E2BIG)
  {
      (void)QTSSModuleUtils::SendErrorResponse(fRequest, qtssClientBadRequest, qtssMsgRequestTooLong);
       fState = kPostProcessingRequest;
       break;
   }

2. 状态机 kHTTPFilteringRequest

该状态机下检测是否为RTSP-over-HTTP tunneling,并直接切换到kHaveNonTunnelMessage状态。由于与RTSP无关,该部分的函数PreFilterForHTTPProxyTunnel(),暂时就不深入研究了。

3. 状态机 kHaveNonTunnelMessage

进入此状态,说明请求报文格式是正确的,请求已进入受理状态,具体操作步骤如下:

a) 创建RTSPRequest对象,用于解析RTSP消息;

b) 此状态中对fReadMutex,fSessionMutex进行加锁,禁止在处理报文的过程中接收以RTP Interleaved接收RTP数据或者发出RTSP响应报文

c) 对错误码E2BIG、QTSS_BadArgument进行处理,响应qtssClientBadRequest;

d) 将状态机跳转到kFilteringRequest下;

4. 状态机kFilteringRequest

a) 刷新超时任务fTimeoutTask,运转RTSP会话的超时机制。

b) 通过fIsDataPacket属性进行判断当前数据是否是一个数据包,而不是一个信令消息。该属性判断方法在RTSPRequestStream::ReadRequest()中。RTP包格式以$字符开头,后面紧跟着一个字节是信道标示符,后面两个字节是数字长度,Darwin就用这个字符区分是否为数据包。

c) 这时第一次开始调用module了,角色为kRTSPFilterRole。注册了该角色模块只有一个QTSSRefMovieModule,

d) SetupRequest(),解析RTSP消息,同时创建一个客户会话(RTPSession),和产生当前请求的客户端连接相关联,这个会话会一直保持,直到客户端的流播放结束。

注意:服务器根据被调用的模块是否对请求做了应答来决定后面的调用(方法HasResponseBeenSent()),如果注册了RTSP Filter Role的某一个模块在被调用的时候对请求作出了应答,服务器将立即调用注册了RTSPPostprocessorRole的模块,不再调用其他尚未调用的注册了RTSP Filter Role的模块,否则服务器调用其它注册了RTSP Filter Role的模块。

5. 状态机kRoutingRequest

这里只走到一个模块QTSSReflectorModule中,调用其RedirectBroadcast()方法,主要是增加两个字段到inParams->inRTSPRequest中。key值分别为qtssRTSPReqRootDir、qtssRTSPReqFilePath。   配置文件中如下两个字段并未设置,上面设置的路径逻辑就不会走到。

	<PREF NAME="redirect_broadcast_keyword" ></PREF>
	<PREF NAME="redirect_broadcasts_dir" ></PREF>	

最后跳转到鉴权状态机kAuthenticatingRequest

6. 状态机kAuthenticatingRequest、kAuthorizingRequest。

这里对鉴权方面后续会单独深入研究,目前项目也不涉及。   鉴权完成后,跳转到核心的状态机kPreprocessingRequest中。

7. 状态机kPreprocessingRequest

遍历调用所有注册了QTSS_RTSPPreProcessor_Role角色的模块。在这个角色模式下,分别处理了每种RTSP消息,比如本次的点播请求的Describe、Setup、Play指令,模块中针对各种消息都有对应的单独函数处理。   处理完每次RTSP请求后即进入下一状态kPostProcessingRequest,待下轮循环进入本状态机再处理下一个RTSP消息。

(以下状态后续补充)

8. 状态机kPostProcessingRequest

9. 状态机kSendingResponse

10.状态机kCleaningUp

清理数据,同时释放kHaveNonTunnelMessage状态中获取的锁。

fSessionMutex.Unlock();
fReadMutex.Unlock();

11.状态机kReadingRequest

【转载请注明出处】:http://blog.csdn.net/longlong530

简单的画了下RTSPSession的状态机流程,如下图:

时间: 2024-08-27 18:20:00

【Darwin学习笔记】之RTSPSession的相关文章

【Darwin学习笔记】之TaskThread

[转载请注明出处]:http://blog.csdn.net/longlong530 学习TaskThread主要有三个类要关注: TaskTreadPool: 任务线程池 TaskThread:任务线程 Task: 任务 1. TaskThreadPool Darwin运行着一个或者多个任务(Task)线程,并将他们统一在线程池TaskThreadPool中管理.任务线程从事件线程中接收RTSP和RTP请求,然后把请求传递到恰当的服务器模块进行处理,把数据包发送给客户端. 缺省情况下,核心服务

【Darwin学习笔记】之EventThread

[转载请注明出处]:http://blog.csdn.net/longlong530 EventThread负责侦听Darwin系统的Socket事件,包括以下两类, 对于两类事件是分别如何处理的,我们从头开始分析. a)   建立新的RTSP连接请求事件 b)   已有RTSP连接上的RTSP请求消息事件 一.  EventThread 的创建 RunServer.cpp 中StartServer函数初始化调用了 Socket::Initialize(),在该函数内即创建了EventThrea

【Darwin学习笔记】之RTSP连接监听初始化

网上有很多大侠已经对Darwin做了详细的剖析,在下仅本着积累经验的目的,将Darwin的学习过程记录下来,同时与网友们交流学习,今天先来分析下Darwin如果根据配置文件监听RTSP连接的流程. 1. Darwin系统初始化,Bool16 QTSServer::Initialize(.....) 2. QTSServer::CreateListeners(...)根据本地xml配置文件中的地址和端口进行监听的建立,主要有两个配置项: <PREF NAME="bind_ip_addr&qu

【Darwin学习笔记】之QTSSReflectorModule的Announce消息处理

RTSP Announce命令是数据源向Darwin服务端主动发起的上报本地媒体sdp信息的命令,在Darwin中处理该命令的函数为QTSSReflectorModule模块的DoAnnounce()函数,下面对该函数的进行剖析: [转载请注明出处]:http://blog.csdn.net/longlong530 1. 判断sAnnounceEnabled是否开启,由以下配置项确定,默认为true <PREF NAME="enable_broadcast_announce" T

【Darwin学习笔记】之QTSSReflectorModule的Describe消息处理

对于QTSSReflectorModule里面的Describe消息只处理sdp类型的资源请求,其他类型的比如mov.mp4等资源会跳转到QTSSFileModule里面,其中mp4文件在Darwin源码中点播需要先hint下.如果想在增加多种视频格式那就要对FileModule进行扩展,在我们的项目中就优化了FileModule,实现了对mp4.avi等各种格式的文件的点播支持.后面的章节我们详细讨论. [转载请注明出处]:http://blog.csdn.net/longlong530 1.

【Darwin学习笔记】之QTSSReflectorModule的Setup消息处理

Setup消息进入到DoSetup函数单独处理,处理流程如下: [转载请注明出处]:http://blog.csdn.net/longlong530 1. 根据关键字qtssRTSPReqTransportMode判断是否为推模式,具体isPush值由Setup请求中的mode值有关,mode="receive" || mode="record"表示isPush为true.对应的解析函数为:void RTSPRequest::ParseModeSubHeader(S

Go学习笔记(一)Let&#39;s 干

加 Golang学习 QQ群共同学习进步成家立业 ^-^ 群号:96933959 简介     Go是Google开发的一种 静态强类型.编译型,并发型,并具有垃圾回收功能的编程语言.为了方便搜索和识别,有时会将其称为Golang. 罗伯特·格瑞史莫,罗勃·派克(Rob Pike)及肯·汤普逊于2007年9月开始设计Go语言,稍后Ian Lance Taylor.Russ Cox加入项目.Go语言是基于Inferno操作系统所开发的.Go语言于2009年11月正式宣布推出,成为开放源代码项目,并

vector 学习笔记

vector 使用练习: /**************************************** * File Name: vector.cpp * Author: sky0917 * Created Time: 2014年04月27日 11:07:33 ****************************************/ #include <iostream> #include <vector> using namespace std; int main

Caliburn.Micro学习笔记(一)----引导类和命名匹配规则

Caliburn.Micro学习笔记(一)----引导类和命名匹配规则 用了几天时间看了一下开源框架Caliburn.Micro 这是他源码的地址http://caliburnmicro.codeplex.com/ 文档也写的很详细,自己在看它的文档和代码时写了一些demo和笔记,还有它实现的原理记录一下 学习Caliburn.Micro要有MEF和MVVM的基础 先说一下他的命名规则和引导类 以后我会把Caliburn.Micro的 Actions IResult,IHandle ICondu