void ProxyRTSPClient::continueAfterPLAY(int resultCode) {
  if (resultCode != 0) {
    // The "PLAY" command failed, so reset the connection with the 'back-end' server and start over,
    // just as if a periodic 'liveness' check with the 'back-end' server had failed:
    continueAfterLivenessCommand(resultCode, fServerSupportsGetParameter);
  }
}
示例#2
0
void ProxyRTSPClient::checkInterPacketGaps_() {
  if (fInterPacketGapMaxTime == 0) return; // we're not checking

  // Check each subsession, counting up how many packets have been received:
  unsigned newTotNumPacketsReceived = 0;

  MediaSubsessionIterator iter(*fOurServerMediaSession.fClientMediaSession);
  MediaSubsession* subsession;
  while ((subsession = iter.next()) != NULL) {
    RTPSource* src = subsession->rtpSource();
    if (src == NULL) continue;
    newTotNumPacketsReceived += src->receptionStatsDB().totNumPacketsReceived();
  }

  //envir() << *this << "::doLivenessCheck fTotNumPacketsReceived: " << fTotNumPacketsReceived
  //                   << ", newTotNumPacketsReceived: " << newTotNumPacketsReceived << "\n";

  if (newTotNumPacketsReceived == fTotNumPacketsReceived) {
    // No additional packets have been received since the last time we
    // checked, so end this stream:
    // *env << "Closing session, because we stopped receiving packets.\n";
    if (fVerbosityLevel > 0) {
      envir() << *this << "::doLivenessCheck last packet received: >" << fInterPacketGapMaxTime 
                       << " seconds ago. Resetting session\n";
    }
    continueAfterLivenessCommand(1/*hack*/, fServerSupportsGetParameter);
  } else {
    fTotNumPacketsReceived = newTotNumPacketsReceived;
    // Check again, after the specified delay:
    fInterPacketGapsTask = envir().taskScheduler().scheduleDelayedTask(fInterPacketGapMaxTime*MILLION, checkInterPacketGaps, this);
  }
}
void ProxyRTSPClient::continueAfterSETUP(int resultCode) {
  if (resultCode != 0) {
    // The "SETUP" command failed, so reset the connection with the 'back-end' server and start over,
    // just as if a periodic 'liveness' check with the 'back-end' server had failed:
    continueAfterLivenessCommand(resultCode, fServerSupportsGetParameter);
    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();
    }
    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
  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);
    }
  }
}