Darwin中RTSP协议的实现

来源:互联网 发布:北京理工大学网络 编辑:程序博客网 时间:2024/05/29 12:15
基本概念

Darwin中RTSP协议的实现

RTSP协议的实现

服务器收到RTSP请求后会创建一个RTSPRequest对象,RTSPRequest对象是由若干属性构成的,这些属性描述了一个RTSP请求的方方面面。刚刚创建的RTSPRequest对象只有qtssRTSPReqFullRequest一个属性被赋值,qtssRTSPReqFullRequest的值是一个完整的RTSP请求,就像下面的样子:

DESCRIBE rtsp://streaming.site.com/foo.mov RTSP/1.0
CSeq: 1
Accept: application/sdp
User-agent: QTS/1.0

接下来,服务器按顺序调用注册了特定角色的模块。需要指出的是,注册了同一角色的不同模块的调用次序是不确定的。如图所示为对RTSP请求的处理过程:

Darwin中RTSP协议的实现
第一个被调用的角色是RTSP Filter Role,调用的时候会携带RTSPrequest对象作为参数。模块可以对RTSPRequest的qtssRTSPReqFullRequest属性进行修改。服务器根据被调用的模块是否对请求做了应答来决定后面的调用,如果注册了RTSP Filter Role的某一个模块在被调用的时候对请求作出了应答,服务器将立即调用注册了RTSP Postprocessor Role的模块,不再调用其他尚未调用的注册了RTSP Filter Role的模块,否则服务器调用其它注册了RTSP Filter Role的模块,所有注册了RTSP Filter Role的模块都被调用后,服务器对RTSP请求进行解析,通过分析qtssRTSPReqFullRequest为其它属性赋值,另外还要创建两个会话,一个会话是RTSP Session,一个会话是Client Session。

RTSP Session与相应的RTSP请求相关联,在客户端关闭RTSP连接的时候会话也被关闭。Client Session与发起请求的客户连接相关联,一直到客户端流媒体播放完毕后被关闭。

接下来,服务器将调用注册了RTSP Route Role的模块,并携带RTSP请求对象作为参数。注册了RTSP Route Role的模块可以对RTSP请求对象的qtssRTSPReqRootDir属性进行修改。同调用注册了RTSP Filter Role的模块时的处理策略一样,服务器在调用注册了RTSP Route Role的模块的时候,如果有模块发送了应答,则立刻调用注册了RTSP Postprocessor Role的模块,否则继续调用注册了RTSP Route Role的其它模块。

当所有注册了RTSP Route Role的模块都被调用了,服务器将调用注册了RTSP Preprocessor Role的模块。注册了RTSP Preprocessor Role的模块根据qtssRTSPReqAbsoluteURL的值判断是否能处理该请求的类型。如果请求的类型和被调用的模块所能处理的类型匹配,则该模块调用QTSS_Write或者QTSS_WriteV对请求进行应答。如果是标准的应答,可以调用QTSS_SendStandardRTSPResponse或者QTSS_AppendRTSPHeader和QTSS_SendRTSPHeaders。如果注册了RTSP Preprocessor Role的某个模块对请求作出了应答,则跳过其它注册了RTSP Preprocessor Role的模块及其他模块,立刻调用注册了RTSP Postprocessor Role的模块。

如果所有注册了RTSP Preprocessor Role的模块都没有对请求作出应答,服务器就会调用注册了RTSP Request Role的模块。注意只有一个模块可以注册RTSP Request Role。注册了RTSP Request Role的模块对请求作出应答。

注册了RTSP Request Role的模块对请求作出应答后,服务器调用注册了RTSP Postprocessor Role的模块,注册了RTSP Postprocessor Role的模块通常做一些统计的工作,比如把统计信息写入日志。

注册了RTSP Prerequest Role或者RTSP Request Role的模块可以向发出请求的客户端发送流媒体数据。当需要向请求客户端发送流媒体数据的时候,注册了RTSP Prerequest Role或者RTSP Request Role的模块调用QTSS_Play,然后服务器就会通过RTP Send Packets Role调用该模块,过程如下图所示:

Darwin中RTSP协议的实现


注册了RTP Send Packets Role的模块调用QTSS_Write或者QTSS_WriteV通过RTP session向客户端发送流媒体数据。模块发送了一些数据后,就返回到服务器,并给出下次调用模块发送数据之前等待的时间。服务器循环调用模块发送流媒体数据,直到所有的流媒体数据都发送完毕或者该会话被暂停或关闭。

改进?

视频服务器的核心只是通过获取流媒体数据,比如QTSS_ReadNextPacket,而不是直接读取文件系统然后再对流进行处理。这样就可以把对于文件系统的读写放到模块中,放到模块中的代码就可以实现对于不同文件系统的读写了。这样还可以在读取文件的同时生成不同的倍速播放流。从而实现不增加存储的情况下可以进行任意倍速的播放。IO通常是视频服务器性能的瓶颈,需要通过AIO和DIO结合来实现IO性能的提升,而文件的AIO刚好用到高性能IO的设计模式。需要核心提供API供模块调用来实现高性能IO。

是不是考虑更进一步,也就是通过模块提供API,这个API包括Setup,Play,Pause,Seek,Stop,GetStatus其中Play可以设定播放的倍速,Setup给出传输层协议-比如UDP或者RTP。也就是读取文件,RTP协议的实现等,统统放到一个模块中实现。不过这有一个问题,就是RTP over RTSP怎么实现?


转自:http://blog.sina.com.cn/s/blog_6a4c492f0100oh4v.html

0 0
原创粉丝点击