RTSP Server会不断用select查询是否有socket连接,如果有则在(*handler->handlerProc)(handler->clientData, resultConditionSet) 进行处理。
在RTSPServer::RTSPClientConnection::incomingRequestHandler1()函数中,从socket读取客户端请求信息,然后解析RTSP命令,在变量fRequestBuffer中保存了RTSP请求信息:
例如:
OPTIONS rtsp://192.168.2.100:8554/3.ts RTSP/1.0
CSeq: 2
User-Agent: LibVLC/2.0.7 (LIVE555 Streaming Media v2012.12.18)
void RTSPServer::RTSPClientConnection::incomingRequestHandler1() {
struct sockaddr_in dummy;
// 'from' address, meaningless in this case
int bytesRead = readSocket(envir(), fClientInputSocket, &fRequestBuffer[fRequestBytesAlreadySeen], fRequestBufferBytesLeft, dummy);
handleRequestBytes(bytesRead);
}
Live555首先预解析请求字符串,判断请求是否符合标准。目前支持解析以下几种命令:
OPTIONS
GET_PARAMETER
SET_PARAMETER
DESCRIBE
SETUP
TEARDOWN
PLAY
PAUSE
然后发送响应给客户端:
例如:
RTSP/1.0 200 OK
CSeq: 2
Date: Wed, Jun 19 2013 16:05:27 GMT
Public: OPTIONS, DESCRIBE, SETUP, TEARDOWN, PLAY, PAUSE, GET_PARAMETER, SET_PARAMETER
如果使用PLAY请求命令,Live555将调用
void RTSPServer::RTSPClientSession
::handleCmd_PLAY(
RTSPServer::RTSPClientConnection* ourClientConnection,
ServerMediaSubsession* subsession,
char const* fullRequestStr)函数进行处理。
请求数据如下:
PLAY rtsp://192.168.2.100:8554/3.ts/ RTSP/1.0
CSeq: 5
User-Agent: LibVLC/2.0.7 (LIVE555 Streaming Media v2012.12.18)
Session: E0406EAB
Range: npt=0.000-
首先定位流的位置,因为调试时使用的是ts流,
void MPEG2TransportFileServerMediaSubsession
::seekStream(
unsigned clientSessionId,
void* streamToken,
double& seekNPT,
double streamDuration,
u_int64_t& numBytes);
之后就是开始播放流,
fStreamStates[i].subsession->startStream(fOurSessionId,
fStreamStates[i].streamToken,
(TaskFunc*)noteClientLiveness, this,
rtpSeqNum, rtpTimestamp,
RTSPServer::RTSPClientConnection::handleAlternativeRequestByte,
ourClientConnection);
该函数内会调用void OnDemandServerMediaSubsession::startStream(),继而调用StreamState::startPlaying()
void OnDemandServerMediaSubsession::startStream(unsigned clientSessionId,
void* streamToken,
TaskFunc* rtcpRRHandler,
void* rtcpRRHandlerClientData,
unsigned short& rtpSeqNum,
unsigned& rtpTimestamp,
ServerRequestAlternativeByteHandler* serverRequestAlternativeByteHandler,
void* serverRequestAlternativeByteHandlerClientData);
在StreamState::startPlaying()中会创建一个RTCPInstance实例,并把客户端地址和端口添加到RTP和RTCPgroupsocks目的地中。再调用RTPSink::startPlaying()开始推送数据。