RTSP连接的建立过程

RTSPServer用类DynamicRTSPServer::CreateNew(* env, rtspServerPortNum, authDB)实现,建立Socket(ourSocket)在TCP的554端口进行监听,然后把连接处理函数句柄RTSPServer::incomingConnectionHandlersocket句柄传给任务调度器taskScheduler

这里,使用了linux下有名的select模型,taskScheduler把554的socket放到了readset中,同时将socket句柄和incomingConnectionHandler句柄相关联,然后main函数进入env.taskScheduler.doEventLoop

select函数只是返回此时是否有socket准备好读写,然后遍历handlersetFD_ISSET判断是否handler所掌管的socket可以用了,如前面提到的incomingConnectionHandler了,在incomingConnectionHandler中创建了RTSPClientSession,开始对这个客户端的会话进行处理。

DESCRIBE请求消息处理过程

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

创建的RTSPClientSession会有一个新的socket在新的port上监听,同时也会有 incomingConnectionHandler,就是说类似于554的处理过程 ,不过这个incomingConnectionHandler是属于RTSPClientSession的,在这个 incomingConnectionHandler中,就有根据cmdName执行不同的Handler,如 handleCmd_DESCRIBE。此时,通过url去确定产生哪种类型的subsession,在一个Session下可以有多个subsession,且它们形成链表,比如在看mpg文件的时候,mpg既包括一个videosubsession, 又包括一个audiosubsession(这样也就不难解决h.264视频编码和g.711音频编码同时播放的问题,它们在一个ServerMediaSession中的subSession中)。

这里,还需要提一下ServerMediaSessionRTSPClientSession的关系,RTSPClientSessionsockethandler关联 ,标记一次rtsp的过程,而在该链接处理DESCRIBE信令时 ,产生ServerMediaSession,标记Server端所能提供的媒体会话。

SETUP

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

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

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

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包了。


txgcwm
764 声望71 粉丝

Linux C/C++


« 上一篇
live555编译

引用和评论

0 条评论