void ProxyRTSPClient::continueAfterLivenessCommand(int resultCode, Boolean serverSupportsGetParameter) {
  if (resultCode != 0) {
    // The periodic 'liveness' command failed, suggesting that the back-end stream is no longer alive.
    // We handle this by resetting our connection state with this server.  Any current clients will be closed, but
    // subsequent clients will cause new RTSP "SETUP"s and "PLAY"s to get done, restarting the stream.
    // Then continue by sending more "DESCRIBE" commands, to try to restore the stream.

    fServerSupportsGetParameter = False; // until we learn otherwise, in response to a future "OPTIONS" command

    if (resultCode < 0) {
      // The 'liveness' command failed without getting a response from the server (otherwise "resultCode" would have been > 0).
      // This suggests that the RTSP connection itself has failed.  Print this error code, in case it's useful for debugging:
      if (fVerbosityLevel > 0) {
	envir() << *this << ": lost connection to server ('errno': " << -resultCode << ").  Resetting...\n";
      }
    }

    reset();
    fOurServerMediaSession.resetDESCRIBEState();

    setBaseURL(fOurURL); // because we'll be sending an initial "DESCRIBE" all over again
    sendDESCRIBE(this);
    return;
  }

  fServerSupportsGetParameter = serverSupportsGetParameter;

  // Schedule the next 'liveness' command (i.e., to tell the back-end server that we're still alive):
  scheduleLivenessCommand();
}
void ProxyRTSPClient::continueAfterDESCRIBE(char const* sdpDescription) {
    if (sdpDescription != NULL) {
        fOurServerMediaSession.continueAfterDESCRIBE(sdpDescription);

        // Unlike most RTSP streams, there might be a long delay between this "DESCRIBE" command (to the downstream server) and the
        // subsequent "SETUP"/"PLAY" - which doesn't occur until the first time that a client requests the stream.
        // To prevent the proxied connection (between us and the downstream server) from timing out, we send periodic
        // "OPTIONS" commands.  (The usual RTCP liveness mechanism wouldn't work here, because RTCP packets don't get sent
        // until after the "PLAY" command.)
        scheduleLivenessCommand();
    } else {
        // The "DESCRIBE" command failed, most likely because the server or the stream is not yet running.
        // Reschedule another "DESCRIBE" command to take place later:
        scheduleDESCRIBECommand();
    }
}
void ProxyRTSPClient::continueAfterOPTIONS(int resultCode) {
    if (resultCode < 0) {
        // The "OPTIONS" command failed without getting a response from the server (otherwise "resultCode" would have been >= 0).
        // From this, we infer that the server (which had previously been running) has now failed - perhaps temporarily.
        // We handle this by resetting our connection state with this server.  Any current clients will have to time out, but
        // subsequent clients will cause new RTSP "SETUP"s and "PLAY"s to get done, restarting the stream.
        if (fVerbosityLevel > 0) {
            envir() << *this << ": lost connection to server ('errno': " << -resultCode << ").  Resetting...\n";
        }
        reset();

        // Also "reset()" each of our "ProxyServerMediaSubsession"s:
        ServerMediaSubsessionIterator iter(fOurServerMediaSession);
        ProxyServerMediaSubsession* psmss;
        while ((psmss = (ProxyServerMediaSubsession*)(iter.next())) != NULL) {
            psmss->reset();
        }
    }

    // Schedule the next RTSP "OPTIONS" command (to show client liveness):
    scheduleLivenessCommand();
}