From 7c728db1f34b90c96102987d22889c8b1d324476 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Wed, 27 Apr 2016 20:46:34 +0300 Subject: [PATCH] rtspsrc: Update caps for TCP whenever they change 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 | 32 ++++++++++++++++++++++++++++++-- gst/rtsp/gstrtspsrc.h | 1 + 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/gst/rtsp/gstrtspsrc.c b/gst/rtsp/gstrtspsrc.c index 1c218e77e6..e671b0ff7a 100644 --- a/gst/rtsp/gstrtspsrc.c +++ b/gst/rtsp/gstrtspsrc.c @@ -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 diff --git a/gst/rtsp/gstrtspsrc.h b/gst/rtsp/gstrtspsrc.h index a665754d7f..88bf305e8f 100644 --- a/gst/rtsp/gstrtspsrc.h +++ b/gst/rtsp/gstrtspsrc.h @@ -103,6 +103,7 @@ struct _GstRTSPStream { gboolean skipped; gboolean eos; gboolean discont; + gboolean need_caps; /* for interleaved mode */ guint8 channel[2];