您的位置:首页 > 其它

【Darwin学习笔记】之RTSPSession点播流程

2017-02-27 16:19 330 查看
今天详细的看了下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状态机,然后在改状态机下响应错误

[cpp] view
plain copy

 print?





// 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。   配置文件中如下两个字段并未设置,上面设置的路径逻辑就不会走到。

[html] view
plain copy

 print?





<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状态中获取的锁。

[cpp] view
plain copy

 print?

fSessionMutex.Unlock();  

fReadMutex.Unlock();  

11.状态机kReadingRequest

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


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

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: