rtspsrc: Update caps for TCP whenever they change
authorSebastian Dröge <sebastian@centricular.com>
Wed, 27 Apr 2016 17:46:34 +0000 (20:46 +0300)
committerSebastian Dröge <sebastian@centricular.com>
Wed, 27 Apr 2016 17:52:32 +0000 (20:52 +0300)
We only changed them for UDP so far, which caused the wrong seqnum-base and
other information to be passed to rtpjitterbuffer/etc when seeking. This
usually wasn't that much of a problem as the code there is robust enough, but
every now and then it causes us to drop up to 32756 packets before we
continue doing anything meaningful.

https://bugzilla.gnome.org/show_bug.cgi?id=765689

gst/rtsp/gstrtspsrc.c
gst/rtsp/gstrtspsrc.h

index 1c218e77e6c902b7bc5f02d9f492a26e680406f5..e671b0ff7aeea90053159269d466a89f41bb49b9 100644 (file)
@@ -3948,8 +3948,10 @@ gst_rtspsrc_configure_caps (GstRTSPSrc * src, GstSegment * segment,
       GST_DEBUG_OBJECT (src, "stream %p, pt %d, caps %" GST_PTR_FORMAT, stream,
           item->pt, caps);
 
-      if (item->pt == stream->default_pt && stream->udpsrc[0]) {
-        g_object_set (stream->udpsrc[0], "caps", caps, NULL);
+      if (item->pt == stream->default_pt) {
+        if (stream->udpsrc[0])
+          g_object_set (stream->udpsrc[0], "caps", caps, NULL);
+        stream->need_caps = TRUE;
       }
     }
   }
@@ -4441,6 +4443,7 @@ gst_rtspsrc_handle_data (GstRTSPSrc * src, GstRTSPMessage * message)
               gst_pad_send_event (ostream->channelpad[0],
                   gst_event_new_caps (caps));
           }
+          ostream->need_caps = FALSE;
 
           if (ostream->profile == GST_RTSP_PROFILE_SAVP ||
               ostream->profile == GST_RTSP_PROFILE_SAVPF)
@@ -4504,6 +4507,28 @@ gst_rtspsrc_handle_data (GstRTSPSrc * src, GstRTSPMessage * message)
     gst_rtspsrc_push_event (src, gst_event_new_segment (&segment));
   }
 
+  if (stream->need_caps) {
+    GstCaps *caps;
+
+    if ((caps = stream_get_caps_for_pt (stream, stream->default_pt))) {
+      /* only streams that have a connection to the outside world */
+      if (stream->setup) {
+        /* Only need to update the TCP caps here, UDP is already handled */
+        if (stream->channelpad[0]) {
+          if (GST_PAD_IS_SRC (stream->channelpad[0]))
+            gst_pad_push_event (stream->channelpad[0],
+                gst_event_new_caps (caps));
+          else
+            gst_pad_send_event (stream->channelpad[0],
+                gst_event_new_caps (caps));
+        }
+        stream->need_caps = FALSE;
+      }
+    }
+
+    stream->need_caps = FALSE;
+  }
+
   if (stream->discont && !is_rtcp) {
     /* mark first RTP buffer as discont */
     GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT);
@@ -7157,7 +7182,10 @@ clear_rtp_base (GstRTSPSrc * src, GstRTSPStream * stream)
     item->caps = gst_caps_make_writable (item->caps);
     s = gst_caps_get_structure (item->caps, 0);
     gst_structure_remove_fields (s, "clock-base", "seqnum-base", NULL);
+    if (item->pt == stream->default_pt && stream->udpsrc[0])
+      g_object_set (stream->udpsrc[0], "caps", item->caps, NULL);
   }
+  stream->need_caps = TRUE;
 }
 
 static GstRTSPResult
index a665754d7fd6efb051d24d53a565b9a3d041d541..88bf305e8fa0b77fba8dbc28c57eb080b5e7f0f1 100644 (file)
@@ -103,6 +103,7 @@ struct _GstRTSPStream {
   gboolean      skipped;
   gboolean      eos;
   gboolean      discont;
+  gboolean      need_caps;
 
   /* for interleaved mode */
   guint8        channel[2];