diff -pru livemedia.2016.11.28_org/liveMedia/include/ProxyServerMediaSession.hh livemedia.2016.11.28_patch_submit/liveMedia/include/ProxyServerMediaSession.hh
--- livemedia.2016.11.28_org/liveMedia/include/ProxyServerMediaSession.hh	2016-11-28 22:42:18.000000000 +0100
+++ livemedia.2016.11.28_patch_submit/liveMedia/include/ProxyServerMediaSession.hh	2017-01-06 14:32:28.272915323 +0100
@@ -50,14 +50,18 @@ public:
   void continueAfterLivenessCommand(int resultCode, Boolean serverSupportsGetParameter);
   void continueAfterSETUP(int resultCode);
   void continueAfterPLAY(int resultCode);
+  void scheduleReset();
 
 private:
   void reset();
+  int connectToServer(int socketNum, portNumBits remotePortNum);
 
   Authenticator* auth() { return fOurAuthenticator; }
 
   void scheduleLivenessCommand();
   static void sendLivenessCommand(void* clientData);
+  void doReset_();
+  static void doReset(void* clientData);
 
   void scheduleDESCRIBECommand();
   static void sendDESCRIBE(void* clientData);
@@ -75,8 +79,8 @@ private:
   class ProxyServerMediaSubsession *fSetupQueueHead, *fSetupQueueTail;
   unsigned fNumSetupsDone;
   unsigned fNextDESCRIBEDelay; // in seconds
-  Boolean fServerSupportsGetParameter, fLastCommandWasPLAY, fResetOnNextLivenessTest;
-  TaskToken fLivenessCommandTask, fDESCRIBECommandTask, fSubsessionTimerTask;
+  Boolean fServerSupportsGetParameter, fLastCommandWasPLAY, fDoneDescribe;
+  TaskToken fLivenessCommandTask, fDESCRIBECommandTask, fSubsessionTimerTask, fResetTask;
 };
 
 
diff -pru livemedia.2016.11.28_org/liveMedia/include/RTSPClient.hh livemedia.2016.11.28_patch_submit/liveMedia/include/RTSPClient.hh
--- livemedia.2016.11.28_org/liveMedia/include/RTSPClient.hh	2016-11-28 22:42:18.000000000 +0100
+++ livemedia.2016.11.28_patch_submit/liveMedia/include/RTSPClient.hh	2017-01-07 11:21:48.561617338 +0100
@@ -246,6 +246,7 @@ protected:
 				   char*& extraHeaders, Boolean& extraHeadersWereAllocated);
       // used to implement "sendRequest()"; subclasses may reimplement this (e.g., when implementing a new command name)
 
+  virtual int connectToServer(int socketNum, portNumBits remotePortNum); // used to implement "openConnection()"; result values are the same
 private: // redefined virtual functions
   virtual Boolean isRTSPClient() const;
 
@@ -271,7 +272,6 @@ private:
   void resetTCPSockets();
   void resetResponseBuffer();
   int openConnection(); // -1: failure; 0: pending; 1: success
-  int connectToServer(int socketNum, portNumBits remotePortNum); // used to implement "openConnection()"; result values are the same
   char* createAuthenticatorString(char const* cmd, char const* url);
   char* createBlocksizeString(Boolean streamUsingTCP);
   void handleRequestError(RequestRecord* request);
diff -pru livemedia.2016.11.28_org/liveMedia/ProxyServerMediaSession.cpp livemedia.2016.11.28_patch_submit/liveMedia/ProxyServerMediaSession.cpp
--- livemedia.2016.11.28_org/liveMedia/ProxyServerMediaSession.cpp	2016-11-28 22:42:18.000000000 +0100
+++ livemedia.2016.11.28_patch_submit/liveMedia/ProxyServerMediaSession.cpp	2017-01-06 16:42:27.312572193 +0100
@@ -222,8 +222,8 @@ static void continueAfterOPTIONS(RTSPCli
   if (resultCode == 0) {
     // Note whether the server told us that it supports the "GET_PARAMETER" command:
     serverSupportsGetParameter = RTSPOptionIsSupported("GET_PARAMETER", resultString);
-  } 
- ((ProxyRTSPClient*)rtspClient)->continueAfterLivenessCommand(resultCode, serverSupportsGetParameter);
+  }
+  ((ProxyRTSPClient*)rtspClient)->continueAfterLivenessCommand(resultCode, serverSupportsGetParameter);
   delete[] resultString;
 }
 
@@ -248,8 +248,8 @@ ProxyRTSPClient::ProxyRTSPClient(ProxySe
 	       tunnelOverHTTPPortNum == (portNumBits)(~0) ? 0 : tunnelOverHTTPPortNum, socketNumToServer),
     fOurServerMediaSession(ourServerMediaSession), fOurURL(strDup(rtspURL)), fStreamRTPOverTCP(tunnelOverHTTPPortNum != 0),
     fSetupQueueHead(NULL), fSetupQueueTail(NULL), fNumSetupsDone(0), fNextDESCRIBEDelay(1),
-    fServerSupportsGetParameter(False), fLastCommandWasPLAY(False), fResetOnNextLivenessTest(False),
-    fLivenessCommandTask(NULL), fDESCRIBECommandTask(NULL), fSubsessionTimerTask(NULL) { 
+    fServerSupportsGetParameter(False), fLastCommandWasPLAY(False), fDoneDescribe(False),
+    fLivenessCommandTask(NULL), fDESCRIBECommandTask(NULL), fSubsessionTimerTask(NULL), fResetTask(NULL) {
   if (username != NULL && password != NULL) {
     fOurAuthenticator = new Authenticator(username, password);
   } else {
@@ -261,11 +261,13 @@ void ProxyRTSPClient::reset() {
   envir().taskScheduler().unscheduleDelayedTask(fLivenessCommandTask); fLivenessCommandTask = NULL;
   envir().taskScheduler().unscheduleDelayedTask(fDESCRIBECommandTask); fDESCRIBECommandTask = NULL;
   envir().taskScheduler().unscheduleDelayedTask(fSubsessionTimerTask); fSubsessionTimerTask = NULL;
+  envir().taskScheduler().unscheduleDelayedTask(fResetTask); fResetTask = NULL;
 
   fSetupQueueHead = fSetupQueueTail = NULL;
   fNumSetupsDone = 0;
   fNextDESCRIBEDelay = 1;
   fLastCommandWasPLAY = False;
+  fDoneDescribe = False;
 
   RTSPClient::reset();
 }
@@ -277,6 +279,21 @@ ProxyRTSPClient::~ProxyRTSPClient() {
   delete[] fOurURL;
 }
 
+int ProxyRTSPClient::connectToServer(int socketNum, portNumBits remotePortNum) {
+  int res;
+  res = RTSPClient::connectToServer(socketNum, remotePortNum);
+  
+  if (res == 0 && fDoneDescribe && fStreamRTPOverTCP)
+  {
+    if (fVerbosityLevel > 0) {
+      envir() << "ProxyRTSPClient::connectToServer calling scheduleReset()\n";
+    }
+    scheduleReset();
+  }
+  
+  return res;
+}
+
 void ProxyRTSPClient::continueAfterDESCRIBE(char const* sdpDescription) {
   if (sdpDescription != NULL) {
     fOurServerMediaSession.continueAfterDESCRIBE(sdpDescription);
@@ -292,14 +309,10 @@ void ProxyRTSPClient::continueAfterDESCR
     // Reschedule another "DESCRIBE" command to take place later:
     scheduleDESCRIBECommand();
   }
+  fDoneDescribe = True;
 }
 
 void ProxyRTSPClient::continueAfterLivenessCommand(int resultCode, Boolean serverSupportsGetParameter) {
-  if (fResetOnNextLivenessTest) {
-    // Hack: We've arranged to reset the connection with the server (regardless of "resultCode"):
-    fResetOnNextLivenessTest = False;
-    resultCode = 2; // arbitrary > 0
-  }
   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
@@ -312,15 +325,12 @@ void ProxyRTSPClient::continueAfterLiven
       // 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";
+	envir() << *this << ": lost connection to server ('errno': " << -resultCode << ").  Scheduling reset...\n";
       }
     }
 
-    reset();
-    fOurServerMediaSession.resetDESCRIBEState();
 
-    setBaseURL(fOurURL); // because we'll be sending an initial "DESCRIBE" all over again
-    sendDESCRIBE(this);
+    scheduleReset();
     return;
   }
 
@@ -334,11 +344,9 @@ void ProxyRTSPClient::continueAfterLiven
 
 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);
+    // The "SETUP" command failed, so arrange to reset the state. (We don't do this now, because it deletes the
+    // "ProxyServerMediaSubsession", and we can't do that during "ProxyServerMediaSubsession::createNewStreamSource()".)
+    scheduleReset();
     return;
   }
 
@@ -385,11 +393,9 @@ void ProxyRTSPClient::continueAfterSETUP
 
 void ProxyRTSPClient::continueAfterPLAY(int resultCode) {
   if (resultCode != 0) {
-    // The "PLAY" 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);
+    // The "PLAY" command failed, so arrange to reset the state. (We don't do this now, because it deletes the
+    // "ProxyServerMediaSubsession", and we can't do that during "ProxyServerMediaSubsession::createNewStreamSource()".)
+    scheduleReset();
     return;
   }
 }
@@ -432,6 +438,30 @@ void ProxyRTSPClient::sendLivenessComman
 #endif
 }
 
+void ProxyRTSPClient::scheduleReset() {
+  if (fVerbosityLevel > 0) {
+    envir() << "ProxyRTSPClient::scheduleReset\n";
+  }
+  envir().taskScheduler().rescheduleDelayedTask(fResetTask, 0, doReset, this);
+}
+
+void ProxyRTSPClient::doReset_() {
+  if (fVerbosityLevel > 0) {
+    envir() << *this << "::doReset\n";
+  }
+
+  reset();
+  fOurServerMediaSession.resetDESCRIBEState();
+
+  setBaseURL(fOurURL); // because we'll be sending an initial "DESCRIBE" all over again
+  sendDESCRIBE(this);
+}
+
+void ProxyRTSPClient::doReset(void* clientData) {
+  ProxyRTSPClient* rtspClient = (ProxyRTSPClient*)clientData;
+  rtspClient->doReset_();
+}
+
 void ProxyRTSPClient::scheduleDESCRIBECommand() {
   // Delay 1s, 2s, 4s, 8s ... 256s until sending the next "DESCRIBE".  Then, keep delaying a random time from [256..511] seconds:
   unsigned secondsToDelay;
@@ -783,7 +813,7 @@ void ProxyServerMediaSubsession::subsess
   // and can reestablish streaming from it only by sending another "DESCRIBE":
   ProxyServerMediaSession* const sms = (ProxyServerMediaSession*)fParentSession;
   ProxyRTSPClient* const proxyRTSPClient = sms->fProxyRTSPClient;
-  proxyRTSPClient->continueAfterLivenessCommand(1/*hack*/, proxyRTSPClient->fServerSupportsGetParameter);
+  proxyRTSPClient->scheduleReset();
 }
 
 
