void CMyRTSPClent::handleSubsessionTimeout() { // We still have one or more subsessions ('tracks') left to "SETUP". But we can't wait any longer for them. Send a "PLAY" now: MediaSession* sess = fOurServerMediaSession.fClientMediaSession; if (sess != NULL) sendPlayCommand(*sess, NULL, -1.0f, -1.0f, 1.0f, fOurAuthenticator); fLastCommandWasPLAY = True; }
void ProxyRTSPClient::continueAfterSETUP(int resultCode) { if (resultCode != 0) { // The "SETUP" command failed, so arrange to reset the state after the next RTSP 'liveness' // command. (We don't do this now, because it deletes the "ProxyServerMediaSubsession", // and we can't do that during "ProxyServerMediaSubsession::createNewStreamSource()".) fResetOnNextLivenessTest = True; envir().taskScheduler().rescheduleDelayedTask(fLivenessCommandTask, 0, sendLivenessCommand, this); return; } if (fVerbosityLevel > 0) { envir() << *this << "::continueAfterSETUP(): head codec: " << fSetupQueueHead->codecName() << "; numSubsessions " << fSetupQueueHead->fParentSession->numSubsessions() << "\n\tqueue:"; for (ProxyServerMediaSubsession* p = fSetupQueueHead; p != NULL; p = p->fNext) { envir() << "\t" << p->codecName(); if (p->fNext == fSetupQueueHead || p->fNext == p) { fprintf(stderr, "##### INTERNAL ERROR 1\n"); break; } //##### TEMP FOR DEBUGGING } envir() << "\n"; } envir().taskScheduler().unscheduleDelayedTask(fSubsessionTimerTask); // in case it had been set // Dequeue the first "ProxyServerMediaSubsession" from our 'SETUP queue'. It will be the one for which this "SETUP" was done: ProxyServerMediaSubsession* smss = fSetupQueueHead; // Assert: != NULL if (fSetupQueueHead == NULL) fprintf(stderr, "##### INTERNAL ERROR 2\n"); else //##### TEMP FOR DEBUGGING fSetupQueueHead = fSetupQueueHead->fNext; if (fSetupQueueHead == NULL) fSetupQueueTail = NULL; if (fSetupQueueHead != NULL) { // There are still entries in the queue, for tracks for which we have still to do a "SETUP". // "SETUP" the first of these now: sendSetupCommand(fSetupQueueHead->fClientMediaSubsession, ::continueAfterSETUP, False, fStreamRTPOverTCP, False, fOurAuthenticator); ++fNumSetupsDone; fSetupQueueHead->fHaveSetupStream = True; } else { if (fNumSetupsDone >= smss->fParentSession->numSubsessions()) { // We've now finished setting up each of our subsessions (i.e., 'tracks'). // Continue by sending a "PLAY" command (an 'aggregate' "PLAY" command, on the whole session): sendPlayCommand(smss->fClientMediaSubsession.parentSession(), ::continueAfterPLAY, -1.0f, -1.0f, 1.0f, fOurAuthenticator); // the "-1.0f" "start" parameter causes the "PLAY" to be sent without a "Range:" header, in case we'd already done // a "PLAY" before (as a result of a 'subsession timeout' (note below)) fLastCommandWasPLAY = True; } else { // Some of this session's subsessions (i.e., 'tracks') remain to be "SETUP". They might get "SETUP" very soon, but it's // also possible - if the remote client chose to play only some of the session's tracks - that they might not. // To allow for this possibility, we set a timer. If the timer expires without the remaining subsessions getting "SETUP", // then we send a "PLAY" command anyway: fSubsessionTimerTask = envir().taskScheduler().scheduleDelayedTask(SUBSESSION_TIMEOUT_SECONDS*MILLION, (TaskFunc*)subsessionTimeout, this); } } }
void CMyRTSPClent::continueAfterSETUP() { if (fVerbosityLevel > 0) { //envir() << *this << "::continueAfterSETUP(): head codec: " << fSetupQueueHead->fClientMediaSubsession.codecName() // << "; numSubsessions " << fSetupQueueHead->fParentSession->numSubsessions() << "\n\tqueue:"; for (CMyServerMediaSubsession* p = fSetupQueueHead; p != NULL; p = p->fNext) { envir() << "\t" << p->fClientMediaSubsession.codecName(); } envir() << "\n"; } envir().taskScheduler().unscheduleDelayedTask(fSubsessionTimerTask); // in case it had been set // Dequeue the first "ProxyServerMediaSubsession" from our 'SETUP queue'. It will be the one for which this "SETUP" was done: CMyServerMediaSubsession* smss = fSetupQueueHead; // Assert: != NULL fSetupQueueHead = fSetupQueueHead->fNext; if (fSetupQueueHead == NULL) fSetupQueueTail = NULL; if (fSetupQueueHead != NULL) { // There are still entries in the queue, for tracks for which we have still to do a "SETUP". // "SETUP" the first of these now: sendSetupCommand(fSetupQueueHead->fClientMediaSubsession, ::continueAfterSETUP, False, fStreamRTPOverTCP, False, fOurAuthenticator); ++fNumSetupsDone; fSetupQueueHead->fHaveSetupStream = True; } else { if (fNumSetupsDone >= smss->GetfParentSession()->numSubsessions()) { // We've now finished setting up each of our subsessions (i.e., 'tracks'). // Continue by sending a "PLAY" command (an 'aggregate' "PLAY" command, on the whole session): sendPlayCommand(smss->fClientMediaSubsession.parentSession(), NULL, -1.0f, -1.0f, 1.0f, fOurAuthenticator); // the "-1.0f" "start" parameter causes the "PLAY" to be sent without a "Range:" header, in case we'd already done // a "PLAY" before (as a result of a 'subsession timeout' (note below)) fLastCommandWasPLAY = True; } else { // Some of this session's subsessions (i.e., 'tracks') remain to be "SETUP". They might get "SETUP" very soon, but it's // also possible - if the remote client chose to play only some of the session's tracks - that they might not. // To allow for this possibility, we set a timer. If the timer expires without the remaining subsessions getting "SETUP", // then we send a "PLAY" command anyway: fSubsessionTimerTask = envir().taskScheduler().scheduleDelayedTask(SUBSESSION_TIMEOUT_SECONDS*MILLION, (TaskFunc*)subsessionTimeout, this); } } }
int CTCP_RTSPClient::startRTSPRequest(char* ip ,int port ,const char *url, const char* Range_clock, float scale) { strcpy(this->m_url, url); int i = connectRtspSrv(ip,port); if( i < 0 )return i; i = sendSomeCommand(url); if(i < 0)return i; i = sendPlayCommand(url, scale, Range_clock); if( i < 0 )return i; i = RecvPlayResponse(); if( i< 0 )return i; return i; }
int CUDP_RTSPClient::startRTSPRequest(char* ip ,int port ,const char *url, const char* Range_clock, float scale) { strcpy(this->m_url, url); strcpy(this->m_realConnectIP, ip); int i = connectRtspSrv(ip,port); if( i < 0 )return i; i = sendSomeCommand(url); if(i < 0)return i; i = sendPlayCommand(url, scale, Range_clock); if( i < 0 )return i; i = HandleIncomingData(); if( i < 0 )return i; if( i >= 0 ) Heartbeat_thread_ = boost::thread(&CUDP_RTSPClient::handleHeartbeatThread , this); return i; }