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);
		}
	}
}
Esempio n. 4
0
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;
}
Esempio n. 5
0
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;
}