uisourcebin: update forwarded properties on change
authorMatthew Waters <matthew@centricular.com>
Mon, 30 Jul 2018 04:56:40 +0000 (14:56 +1000)
committerEdward Hervey <bilboed@bilboed.com>
Wed, 7 Nov 2018 15:10:05 +0000 (15:10 +0000)
Allows changing queueing properties at runtime

https://gitlab.freedesktop.org/gstreamer/gst-plugins-base/issues/60

gst/playback/gsturisourcebin.c

index d91aa9d715e0d897000762e13886b7feee7b80fa..e8f8ecda3a04e8420bdf57a32bea35bb235b7ef9 100644 (file)
@@ -209,6 +209,12 @@ enum
 #define DEFAULT_LOW_WATERMARK       0.01
 #define DEFAULT_HIGH_WATERMARK      0.99
 
+#define ACTUAL_DEFAULT_BUFFER_SIZE  10 * 1024 * 1024    /* The value used for byte limits when buffer-size == -1 */
+#define ACTUAL_DEFAULT_BUFFER_DURATION  5 * GST_SECOND  /* The value used for time limits when buffer-duration == -1 */
+
+#define GET_BUFFER_SIZE(u) ((u)->buffer_size == -1 ? ACTUAL_DEFAULT_BUFFER_SIZE : (u)->buffer_size)
+#define GET_BUFFER_DURATION(u) ((u)->buffer_duration == -1 ? ACTUAL_DEFAULT_BUFFER_DURATION : (u)->buffer_duration)
+
 #define DEFAULT_CAPS (gst_static_caps_get (&default_raw_caps))
 enum
 {
@@ -272,6 +278,8 @@ static void free_output_slot_async (GstURISourceBin * urisrc,
 static GstPad *create_output_pad (GstURISourceBin * urisrc, GstPad * pad);
 static void remove_buffering_msgs (GstURISourceBin * bin, GstObject * src);
 
+static void update_queue_values (GstURISourceBin * urisrc);
+
 static void
 gst_uri_source_bin_class_init (GstURISourceBinClass * klass)
 {
@@ -496,9 +504,11 @@ gst_uri_source_bin_set_property (GObject * object, guint prop_id,
       break;
     case PROP_BUFFER_SIZE:
       urisrc->buffer_size = g_value_get_int (value);
+      update_queue_values (urisrc);
       break;
     case PROP_BUFFER_DURATION:
       urisrc->buffer_duration = g_value_get_int64 (value);
+      update_queue_values (urisrc);
       break;
     case PROP_DOWNLOAD:
       urisrc->download = g_value_get_boolean (value);
@@ -510,10 +520,12 @@ gst_uri_source_bin_set_property (GObject * object, guint prop_id,
       urisrc->ring_buffer_max_size = g_value_get_uint64 (value);
       break;
     case PROP_LOW_WATERMARK:
-      dec->low_watermark = g_value_get_double (value);
+      urisrc->low_watermark = g_value_get_double (value);
+      update_queue_values (urisrc);
       break;
     case PROP_HIGH_WATERMARK:
-      dec->high_watermark = g_value_get_double (value);
+      urisrc->high_watermark = g_value_get_double (value);
+      update_queue_values (urisrc);
       break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -563,10 +575,10 @@ gst_uri_source_bin_get_property (GObject * object, guint prop_id,
       g_value_set_uint64 (value, urisrc->ring_buffer_max_size);
       break;
     case PROP_LOW_WATERMARK:
-      g_value_set_double (value, dec->low_watermark);
+      g_value_set_double (value, urisrc->low_watermark);
       break;
     case PROP_HIGH_WATERMARK:
-      g_value_set_double (value, dec->high_watermark);
+      g_value_set_double (value, urisrc->high_watermark);
       break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -574,11 +586,6 @@ gst_uri_source_bin_get_property (GObject * object, guint prop_id,
   }
 }
 
-
-#define DEFAULT_QUEUE_SIZE          (3 * GST_SECOND)
-#define DEFAULT_QUEUE_MIN_THRESHOLD ((DEFAULT_QUEUE_SIZE * 30) / 100)
-#define DEFAULT_QUEUE_THRESHOLD     ((DEFAULT_QUEUE_SIZE * 95) / 100)
-
 static gboolean
 copy_sticky_events (GstPad * pad, GstEvent ** event, gpointer user_data)
 {
@@ -886,19 +893,19 @@ pre_queue_event_probe (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
 }
 
 static void
-update_byte_limits (GstElement * elem, gpointer user_data)
+update_queue_values (GstURISourceBin * urisrc)
 {
-  GstURISourceBin *urisrc = GST_URI_SOURCE_BIN (elem);
+  gint64 duration;
+  guint buffer_size;
+  gdouble low_watermark, high_watermark;
   guint64 cumulative_bitrate = 0;
   GSList *cur;
 
   GST_URI_SOURCE_BIN_LOCK (urisrc);
-  if (urisrc->buffer_size == -1) {
-    GST_TRACE_OBJECT (urisrc, "Buffer size not set, not recalculating queue "
-        "limits");
-    GST_URI_SOURCE_BIN_UNLOCK (urisrc);
-    return;
-  }
+  duration = GET_BUFFER_DURATION (urisrc);
+  buffer_size = GET_BUFFER_SIZE (urisrc);
+  low_watermark = urisrc->low_watermark;
+  high_watermark = urisrc->high_watermark;
 
   for (cur = urisrc->out_slots; cur != NULL; cur = g_slist_next (cur)) {
     OutputSlotInfo *slot = (OutputSlotInfo *) (cur->data);
@@ -920,8 +927,8 @@ update_byte_limits (GstElement * elem, gpointer user_data)
   }
 
   GST_DEBUG_OBJECT (urisrc, "recalculating queue limits with cumulative "
-      "bitrate %" G_GUINT64_FORMAT " and buffer size %u", cumulative_bitrate,
-      urisrc->buffer_size);
+      "bitrate %" G_GUINT64_FORMAT ", buffer size %u, buffer duration %"
+      G_GINT64_FORMAT, cumulative_bitrate, buffer_size, duration);
 
   for (cur = urisrc->out_slots; cur != NULL; cur = g_slist_next (cur)) {
     OutputSlotInfo *slot = (OutputSlotInfo *) (cur->data);
@@ -935,18 +942,23 @@ update_byte_limits (GstElement * elem, gpointer user_data)
       }
 
       byte_limit =
-          gst_util_uint64_scale (urisrc->buffer_size, bitrate,
-          cumulative_bitrate);
+          gst_util_uint64_scale (buffer_size, bitrate, cumulative_bitrate);
     } else {
-      byte_limit = urisrc->buffer_size;
+      /* if not all queue's have valid bitrates, use the buffer-size as the
+       * limit */
+      byte_limit = buffer_size;
     }
 
     GST_DEBUG_OBJECT (urisrc,
-        "calculated new byte limit for queue2 %" GST_PTR_FORMAT ", %u",
-        slot->queue, byte_limit);
-    g_object_set (G_OBJECT (slot->queue), "max-size-bytes", byte_limit, NULL);
+        "calculated new limits for queue-like element %" GST_PTR_FORMAT
+        ", bytes:%u, time:%" G_GUINT64_FORMAT
+        ", low-watermark:%f, high-watermark:%f",
+        slot->queue, byte_limit, (guint64) duration, low_watermark,
+        high_watermark);
+    g_object_set (G_OBJECT (slot->queue), "max-size-bytes", byte_limit,
+        "max-size-time", (guint64) duration, "low-watermark", low_watermark,
+        "high-watermark", high_watermark, NULL);
   }
-
   GST_URI_SOURCE_BIN_UNLOCK (urisrc);
 }
 
@@ -956,7 +968,8 @@ on_queue_bitrate_changed (GstElement * queue, GParamSpec * pspec,
 {
   GstURISourceBin *urisrc = GST_URI_SOURCE_BIN (user_data);
 
-  gst_element_call_async (GST_ELEMENT (urisrc), update_byte_limits, NULL, NULL);
+  gst_element_call_async (GST_ELEMENT (urisrc),
+      (GstElementCallAsyncFunc) update_queue_values, NULL, NULL);
 }
 
 /* Called with lock held */
@@ -1052,13 +1065,11 @@ get_output_slot (GstURISourceBin * urisrc, gboolean do_download,
     g_object_set (queue, "low-percent", 1, "high-percent", 60, NULL);
   }
 
-  /* If buffer size or duration are set, set them on the element */
-  if (urisrc->buffer_size != -1)
-    g_object_set (queue, "max-size-bytes", urisrc->buffer_size, NULL);
-  if (urisrc->buffer_duration != -1)
-    g_object_set (queue, "max-size-time", urisrc->buffer_duration, NULL);
-  g_object_set (queue, "low-watermark", urisrc->low_watermark,
-      "high-watermark", urisrc->high_watermark, NULL);
+  /* set the necessary limits on the queue-like elements */
+  g_object_set (queue, "max-size-bytes", GET_BUFFER_SIZE (urisrc),
+      "max-size-time", (guint64) GET_BUFFER_DURATION (urisrc),
+      "low-watermark", urisrc->low_watermark, "high-watermark",
+      urisrc->high_watermark, NULL);
 #if 0
   /* Disabled because this makes initial startup slower for radio streams */
   else {