精通
英语
和
开源
,
擅长
开发
与
培训
,
胸怀四海
第一信赖
void RTSPServer::RTSPClientSession::handleCmd_PLAY(
ServerMediaSubsession* subsession,
char const* cseq,
char const* fullRequestStr)
{
//分析"Scale:"头部 ----------------------------------------------------------该函数主要做了以下动作
//Scale头,指示了播放的速率,scale = 1为正常播放,大于1快进,小于0则表示快退
//分析"Range:"头部
//"Range:"头部,表示要播放的时间范围。如Range: npt=0.000-,从0时刻开始播放看到结束
//不含Range 首部域的PLAY 请求也是合法的。它从媒体流开头开始播放,直到媒体流被暂停
//根据要求,在每个subsession上进行seeking/scaling操作
//计算流的播放时间streamDuration
// Now, start streaming:
for (i = 0; i < fNumStreamStates; ++i) {
if (subsession == NULL /* means: aggregated operation */
|| subsession == fStreamStates[i].subsession) {
unsigned short rtpSeqNum = 0;
unsigned rtpTimestamp = 0;
//开始各个subsession上的数据传输, 即开始播放了(见2.3)
fStreamStates[i].subsession->startStream(fOurSessionId, -----------------------开始真正的传输
void OnDemandServerMediaSubsession::startStream(unsigned clientSessionId, ------------------------------------------------startStream关键分析
void* serverRequestAlternativeByteHandlerClientData) {
StreamState* streamState = (StreamState*)streamToken;
Destinations* destinations
= (Destinations*)(fDestinationsHashTable->Lookup((char const*)clientSessionId)); --------------------------------------------------之前已经加到hash表
if (streamState != NULL) {
streamState->startPlaying(destinations,
}
}
}
void StreamState::startPlaying(Destinations* dests, ----------------------------------------------------------------------------------------startPlaying关键分析
TaskFunc* rtcpRRHandler, void* rtcpRRHandlerClientData,
ServerRequestAlternativeByteHandler* serverRequestAlternativeByteHandler,
void* serverRequestAlternativeByteHandlerClientData) {
if (dests == NULL) return;
//创建RTCPInstance实例 -------------------------------------------------------------------------------------------------------------------RTCP监控调试作用
if (dests->isTCP) {
//使用TCP传输RTP 和 RTCP
// Change RTP and RTCP to use the TCP socket instead of UDP:
if (fRTPSink != NULL) {
fRTPSink->addStreamSocket(dests->tcpSocketNum, dests->rtpChannelId);
fRTPSink->setServerRequestAlternativeByteHandler(dests->tcpSocketNum, serverRequestAlternativeByteHandler, serverRequestAlternativeByteHandlerClientData);
}
} else {
//使用UDP传输RTP、RTCP
}
}
//下面调用sink上的sdtartPlaying函数开始传输数据
if (!fAreCurrentlyPlaying && fMediaSource != NULL) {
if (fRTPSink != NULL) { //通过RTP协议传输
fRTPSink->startPlaying(*fMediaSource, afterPlayingStreamState, this);
fAreCurrentlyPlaying = True;
} else if (fUDPSink != NULL) { //裸的UDP数据包,不使用RTP协议
}
}
}