rtspsrc: Also handle redirect on PLAY
authorMatt Staples <staples255@gmail.com>
Fri, 21 Oct 2016 17:31:00 +0000 (17:31 +0000)
committerSebastian Dröge <sebastian@centricular.com>
Tue, 1 Nov 2016 18:14:35 +0000 (20:14 +0200)
https://bugzilla.gnome.org/show_bug.cgi?id=772610

gst/rtsp/gstrtspsrc.c

index 7e0d85a..2880ffc 100644 (file)
@@ -343,13 +343,13 @@ typedef struct
 } PtMapItem;
 
 /* commands we send to out loop to notify it of events */
-#define CMD_OPEN       (1 << 0)
-#define CMD_PLAY       (1 << 1)
-#define CMD_PAUSE      (1 << 2)
-#define CMD_CLOSE      (1 << 3)
-#define CMD_WAIT       (1 << 4)
-#define CMD_RECONNECT  (1 << 5)
-#define CMD_LOOP       (1 << 6)
+#define CMD_OPEN       (1 << 0)
+#define CMD_PLAY       (1 << 1)
+#define CMD_PAUSE      (1 << 2)
+#define CMD_CLOSE      (1 << 3)
+#define CMD_WAIT       (1 << 4)
+#define CMD_RECONNECT  (1 << 5)
+#define CMD_LOOP       (1 << 6)
 
 /* mask for all commands */
 #define CMD_ALL         ((CMD_LOOP << 1) - 1)
@@ -4881,30 +4881,26 @@ gst_rtspsrc_reconnect (GstRTSPSrc * src, gboolean async)
   if (!restart)
     goto done;
 
-  /* unless redirect, try tcp */
-  if (!src->need_redirect)
-    src->cur_protocols = GST_RTSP_LOWER_TRANS_TCP;
+  /* we can try only TCP now */
+  src->cur_protocols = GST_RTSP_LOWER_TRANS_TCP;
 
   /* close and cleanup our state */
   if ((res = gst_rtspsrc_close (src, async, FALSE)) < 0)
     goto done;
 
-  /* unless redirect, see if we have TCP left to try. Also don't 
-   * try TCP when we were configured with an SDP. */
-  if (!src->need_redirect && (!(src->protocols & GST_RTSP_LOWER_TRANS_TCP)
-          || src->from_sdp))
+  /* see if we have TCP left to try. Also don't try TCP when we were configured
+   * with an SDP. */
+  if (!(src->protocols & GST_RTSP_LOWER_TRANS_TCP) || src->from_sdp)
     goto no_protocols;
 
-  if (!src->need_redirect) {
-    /* We post a warning message now to inform the user
-     * that nothing happened. It's most likely a firewall thing. */
-    GST_ELEMENT_WARNING (src, RESOURCE, READ, (NULL),
-        ("Could not receive any UDP packets for %.4f seconds, maybe your "
-            "firewall is blocking it. Retrying using a tcp connection.",
-            gst_guint64_to_gdouble (src->udp_timeout) / 1000000.0));
-  }
+  /* We post a warning message now to inform the user
+   * that nothing happened. It's most likely a firewall thing. */
+  GST_ELEMENT_WARNING (src, RESOURCE, READ, (NULL),
+      ("Could not receive any UDP packets for %.4f seconds, maybe your "
+          "firewall is blocking it. Retrying using a tcp connection.",
+          gst_guint64_to_gdouble (src->udp_timeout) / 1000000.0));
 
-  /* unless redirect, open new connection using tcp */
+  /* open new connection using tcp */
   if (gst_rtspsrc_open (src, async) < 0)
     goto open_failed;
 
@@ -6770,7 +6766,7 @@ restart:
               NULL)) < 0)
     goto send_error;
 
-  /* we only perform redirect for the describe, currently */
+  /* we only perform redirect for describe and play, currently */
   if (src->need_redirect) {
     /* close connection, we don't have to send a TEARDOWN yet, ignore the
      * result. */
@@ -7256,6 +7252,7 @@ gst_rtspsrc_play (GstRTSPSrc * src, GstSegment * segment, gboolean async)
 
   GST_DEBUG_OBJECT (src, "PLAY...");
 
+restart:
   if ((res = gst_rtspsrc_ensure_open (src, async)) < 0)
     goto open_failed;
 
@@ -7328,6 +7325,18 @@ gst_rtspsrc_play (GstRTSPSrc * src, GstSegment * segment, gboolean async)
     if ((res = gst_rtspsrc_send (src, conn, &request, &response, NULL)) < 0)
       goto send_error;
 
+    if (src->need_redirect) {
+      GST_DEBUG_OBJECT (src,
+          "redirect: tearing down and restarting with new url");
+      /* teardown and restart with new url */
+      gst_rtspsrc_close (src, TRUE, FALSE);
+      /* reset protocols to force re-negotiation with redirected url */
+      src->cur_protocols = src->protocols;
+      gst_rtsp_message_unset (&request);
+      gst_rtsp_message_unset (&response);
+      goto restart;
+    }
+
     /* seek may have silently failed as it is not supported */
     if (!(src->methods & GST_RTSP_PLAY)) {
       GST_DEBUG_OBJECT (src, "PLAY Range not supported; re-enable PLAY");