rtsp-media: query the position on active streams if media is complete
authorBranko Subasic <branko@axis.com>
Tue, 3 Apr 2018 06:57:47 +0000 (08:57 +0200)
committerSebastian Dröge <sebastian@centricular.com>
Wed, 4 Apr 2018 07:05:38 +0000 (10:05 +0300)
If the media is complete, i.e. one or more streams have been configured
with sinks, then we want to query the position on those streams only.
A query on an incomplete stream may return a position that originates from
an earlier preroll.

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

gst/rtsp-server/rtsp-media.c
tests/check/gst/media.c

index 217dc35..b6d69c6 100644 (file)
@@ -228,6 +228,7 @@ static gboolean wait_preroll (GstRTSPMedia * media);
 static GstElement *find_payload_element (GstElement * payloader);
 
 static guint gst_rtsp_media_signals[SIGNAL_LAST] = { 0 };
+static gboolean check_complete (GstRTSPMedia * media);
 
 #define C_ENUM(v) ((gint) v)
 
@@ -593,6 +594,7 @@ gst_rtsp_media_set_property (GObject * object, guint propid,
 typedef struct
 {
   gint64 position;
+  gboolean complete_streams_only;
   gboolean ret;
 } DoQueryPositionData;
 
@@ -601,6 +603,12 @@ do_query_position (GstRTSPStream * stream, DoQueryPositionData * data)
 {
   gint64 tmp;
 
+  if (data->complete_streams_only && !gst_rtsp_stream_is_complete (stream))
+  {
+    GST_DEBUG_OBJECT (stream, "stream not complete, do not query position");
+    return;
+  }
+
   if (gst_rtsp_stream_query_position (stream, &tmp)) {
     data->position = MIN (data->position, tmp);
     data->ret = TRUE;
@@ -621,6 +629,15 @@ default_query_position (GstRTSPMedia * media, gint64 * position)
   data.position = G_MAXINT64;
   data.ret = FALSE;
 
+  /* if the media is complete, i.e. one or more streams have been configured
+   * with sinks, then we want to query the position on those streams only.
+   * a query on an incmplete stream may return a position that originates from
+   * an earlier preroll */
+  if (check_complete (media))
+    data.complete_streams_only = TRUE;
+  else
+    data.complete_streams_only = FALSE;
+
   g_ptr_array_foreach (priv->streams, (GFunc) do_query_position, &data);
 
   if (!data.ret)
index 38c2dc3..20527fc 100644 (file)
@@ -127,6 +127,8 @@ GST_START_TEST (test_media_seek_one_active_stream)
   GstRTSPThreadPool *pool;
   GstRTSPThread *thread;
   GstRTSPTransport *transport;
+  char *range_str;
+  GstRTSPTimeRange *play_range;
 
   factory = gst_rtsp_media_factory_new ();
   fail_if (gst_rtsp_media_factory_is_shared (factory));
@@ -174,7 +176,15 @@ GST_START_TEST (test_media_seek_one_active_stream)
   /* the media is seekable now */
   fail_unless (gst_rtsp_media_seek (media, range));
 
+  /* verify that we got the expected range, 'npt=3.0-' */
+  range_str = gst_rtsp_media_get_range_string (media, TRUE, GST_RTSP_RANGE_NPT);
+  fail_unless (gst_rtsp_range_parse (range_str, &play_range) == GST_RTSP_OK);
+  fail_unless (play_range->min.seconds == range->min.seconds);
+  fail_unless (play_range->max.seconds == range->max.seconds);
+
   gst_rtsp_range_free (range);
+  gst_rtsp_range_free (play_range);
+  g_free (range_str);
 
   fail_unless (gst_rtsp_media_unprepare (media));
   g_object_unref (media);
@@ -189,7 +199,6 @@ GST_START_TEST (test_media_seek_one_active_stream)
 
 GST_END_TEST;
 
-
 GST_START_TEST (test_media_seek_no_sinks)
 {
   GstRTSPMediaFactory *factory;