appsrc: add max-buffers property
authorEunhye Choi <eunhae1.choi@samsung.com>
Tue, 8 Jun 2021 10:50:26 +0000 (19:50 +0900)
committerEunhye Choi <eunhae1.choi@samsung.com>
Wed, 9 Jun 2021 09:36:44 +0000 (18:36 +0900)
- max-buffers is about the max number of queued buffers
  which is from upstream source code

Change-Id: I600401b44bffdff7ed7689a2f2670beabb95ca00

gst-libs/gst/app/gstappsrc.c
gst-libs/gst/app/gstappsrc.h
packaging/gst-plugins-base.spec

index 66ad05e..4ec26d6 100644 (file)
@@ -121,7 +121,11 @@ struct _GstAppSrcPrivate
   gint64 size;
   GstClockTime duration;
   GstAppStreamType stream_type;
+#ifdef TIZEN_FEATURE_UPSTREAM
+  guint64 max_bytes, max_buffers;
+#else
   guint64 max_bytes;
+#endif
   GstFormat format;
   gboolean block;
   gchar *uri;
@@ -129,7 +133,11 @@ struct _GstAppSrcPrivate
   gboolean flushing;
   gboolean started;
   gboolean is_eos;
+#ifdef TIZEN_FEATURE_UPSTREAM
+  guint64 queued_bytes, queued_buffers;
+#else
   guint64 queued_bytes;
+#endif
   guint64 offset;
   GstAppStreamType current_type;
 
@@ -165,6 +173,9 @@ enum
 #define DEFAULT_PROP_SIZE          -1
 #define DEFAULT_PROP_STREAM_TYPE   GST_APP_STREAM_TYPE_STREAM
 #define DEFAULT_PROP_MAX_BYTES     200000
+#ifdef TIZEN_FEATURE_UPSTREAM
+#define DEFAULT_PROP_MAX_BUFFERS   0
+#endif
 #define DEFAULT_PROP_FORMAT        GST_FORMAT_BYTES
 #define DEFAULT_PROP_BLOCK         FALSE
 #define DEFAULT_PROP_IS_LIVE       FALSE
@@ -182,6 +193,9 @@ enum
   PROP_SIZE,
   PROP_STREAM_TYPE,
   PROP_MAX_BYTES,
+#ifdef TIZEN_FEATURE_UPSTREAM
+  PROP_MAX_BUFFERS,
+#endif
   PROP_FORMAT,
   PROP_BLOCK,
   PROP_IS_LIVE,
@@ -314,6 +328,22 @@ gst_app_src_class_init (GstAppSrcClass * klass)
           "The maximum number of bytes to queue internally (0 = unlimited)",
           0, G_MAXUINT64, DEFAULT_PROP_MAX_BYTES,
           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+#ifdef TIZEN_FEATURE_UPSTREAM
+  /**
+   * GstAppSrc:max-buffers:
+   *
+   * The maximum amount of buffers that can be queued internally.
+   * After the maximum amount of buffers are queued, appsrc will emit the
+   * "enough-data" signal.
+   *
+   * Since: 1.20
+   */
+  g_object_class_install_property (gobject_class, PROP_MAX_BUFFERS,
+      g_param_spec_uint64 ("max-buffers", "Max buffers",
+          "The maximum number of buffers to queue internally (0 = unlimited)",
+          0, G_MAXUINT64, DEFAULT_PROP_MAX_BUFFERS,
+          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+#endif
   /**
    * GstAppSrc::block:
    *
@@ -581,6 +611,9 @@ gst_app_src_init (GstAppSrc * appsrc)
   priv->duration = DEFAULT_PROP_DURATION;
   priv->stream_type = DEFAULT_PROP_STREAM_TYPE;
   priv->max_bytes = DEFAULT_PROP_MAX_BYTES;
+#ifdef TIZEN_FEATURE_UPSTREAM
+  priv->max_buffers = DEFAULT_PROP_MAX_BUFFERS;
+#endif
   priv->format = DEFAULT_PROP_FORMAT;
   priv->block = DEFAULT_PROP_BLOCK;
   priv->min_latency = DEFAULT_PROP_MIN_LATENCY;
@@ -614,6 +647,9 @@ gst_app_src_flush_queued (GstAppSrc * src, gboolean retain_last_caps)
   }
 
   priv->queued_bytes = 0;
+#ifdef TIZEN_FEATURE_UPSTREAM
+  priv->queued_buffers = 0;
+#endif
 }
 
 static void
@@ -707,6 +743,11 @@ gst_app_src_set_property (GObject * object, guint prop_id,
     case PROP_MAX_BYTES:
       gst_app_src_set_max_bytes (appsrc, g_value_get_uint64 (value));
       break;
+#ifdef TIZEN_FEATURE_UPSTREAM
+    case PROP_MAX_BUFFERS:
+      gst_app_src_set_max_buffers (appsrc, g_value_get_uint64 (value));
+      break;
+#endif
     case PROP_FORMAT:
       priv->format = g_value_get_enum (value);
       break;
@@ -760,6 +801,11 @@ gst_app_src_get_property (GObject * object, guint prop_id, GValue * value,
     case PROP_MAX_BYTES:
       g_value_set_uint64 (value, gst_app_src_get_max_bytes (appsrc));
       break;
+#ifdef TIZEN_FEATURE_UPSTREAM
+    case PROP_MAX_BUFFERS:
+      g_value_set_uint64 (value, gst_app_src_get_max_buffers (appsrc));
+      break;
+#endif
     case PROP_FORMAT:
       g_value_set_enum (value, priv->format);
       break;
@@ -1182,6 +1228,9 @@ gst_app_src_create (GstBaseSrc * bsrc, guint64 offset, guint size,
     /* return data as long as we have some */
     if (!gst_queue_array_is_empty (priv->queue)) {
       guint buf_size;
+#ifdef TIZEN_FEATURE_UPSTREAM
+      guint n_buffers = 0;
+#endif
       GstMiniObject *obj = gst_queue_array_pop_head (priv->queue);
 
       if (GST_IS_CAPS (obj)) {
@@ -1216,6 +1265,9 @@ gst_app_src_create (GstBaseSrc * bsrc, guint64 offset, guint size,
       if (GST_IS_BUFFER (obj)) {
         *buf = GST_BUFFER (obj);
         buf_size = gst_buffer_get_size (*buf);
+#ifdef TIZEN_FEATURE_UPSTREAM
+        n_buffers = 1;
+#endif
         GST_LOG_OBJECT (appsrc, "have buffer %p of size %u", *buf, buf_size);
       } else {
         GstBufferList *buffer_list;
@@ -1226,6 +1278,9 @@ gst_app_src_create (GstBaseSrc * bsrc, guint64 offset, guint size,
 
         buf_size = gst_buffer_list_calculate_size (buffer_list);
 
+#ifdef TIZEN_FEATURE_UPSTREAM
+        n_buffers = gst_buffer_list_length (buffer_list);
+#endif
         GST_LOG_OBJECT (appsrc, "have buffer list %p of size %u, %u buffers",
             buffer_list, buf_size, gst_buffer_list_length (buffer_list));
 
@@ -1235,6 +1290,9 @@ gst_app_src_create (GstBaseSrc * bsrc, guint64 offset, guint size,
 
       priv->queued_bytes -= buf_size;
 
+#ifdef TIZEN_FEATURE_UPSTREAM
+      priv->queued_buffers -= n_buffers;
+#endif
       /* only update the offset when in random_access mode */
       if (priv->stream_type == GST_APP_STREAM_TYPE_RANDOM_ACCESS)
         priv->offset += buf_size;
@@ -1244,11 +1302,24 @@ gst_app_src_create (GstBaseSrc * bsrc, guint64 offset, guint size,
         g_cond_broadcast (&priv->cond);
 
       /* see if we go lower than the min-percent */
+#ifdef TIZEN_FEATURE_UPSTREAM
+      if (priv->min_percent) {
+        if ((priv->max_bytes
+                && priv->queued_bytes * 100 / priv->max_bytes <=
+                priv->min_percent) || (priv->max_buffers
+                && priv->queued_buffers * 100 / priv->max_buffers <=
+                priv->min_percent)) {
+          /* ignore flushing state, we got a buffer and we will return it now.
+           * Errors will be handled in the next round */
+          gst_app_src_emit_need_data (appsrc, size);
+        }
+#else
       if (priv->min_percent && priv->max_bytes) {
         if (priv->queued_bytes * 100 / priv->max_bytes <= priv->min_percent)
           /* ignore flushing state, we got a buffer and we will return it now.
            * Errors will be handled in the next round */
           gst_app_src_emit_need_data (appsrc, size);
+#endif
       }
       ret = GST_FLOW_OK;
       break;
@@ -1619,6 +1690,67 @@ gst_app_src_get_current_level_bytes (GstAppSrc * appsrc)
   return queued;
 }
 
+#ifdef TIZEN_FEATURE_UPSTREAM
+/**
+ * gst_app_src_set_max_buffers:
+ * @appsrc: a #GstAppSrc
+ * @max: the maximum number of buffers to queue
+ *
+ * Set the maximum amount of buffers that can be queued in @appsrc.
+ * After the maximum amount of buffers are queued, @appsrc will emit the
+ * "enough-data" signal.
+ *
+ * Since: 1.20
+ */
+void
+gst_app_src_set_max_buffers (GstAppSrc * appsrc, guint64 max)
+{
+  GstAppSrcPrivate *priv;
+
+  g_return_if_fail (GST_IS_APP_SRC (appsrc));
+
+  priv = appsrc->priv;
+
+  g_mutex_lock (&priv->mutex);
+  if (max != priv->max_buffers) {
+    GST_DEBUG_OBJECT (appsrc, "setting max-buffers to %" G_GUINT64_FORMAT, max);
+    priv->max_buffers = max;
+    /* signal the change */
+    g_cond_broadcast (&priv->cond);
+  }
+  g_mutex_unlock (&priv->mutex);
+}
+
+/**
+ * gst_app_src_get_max_buffers:
+ * @appsrc: a #GstAppSrc
+ *
+ * Get the maximum amount of buffers that can be queued in @appsrc.
+ *
+ * Returns: The maximum amount of buffers that can be queued.
+ *
+ * Since: 1.20
+ */
+guint64
+gst_app_src_get_max_buffers (GstAppSrc * appsrc)
+{
+  guint64 result;
+  GstAppSrcPrivate *priv;
+
+  g_return_val_if_fail (GST_IS_APP_SRC (appsrc), 0);
+
+  priv = appsrc->priv;
+
+  g_mutex_lock (&priv->mutex);
+  result = priv->max_buffers;
+  GST_DEBUG_OBJECT (appsrc, "getting max-buffers of %" G_GUINT64_FORMAT,
+      result);
+  g_mutex_unlock (&priv->mutex);
+
+  return result;
+}
+#endif
+
 static void
 gst_app_src_set_latencies (GstAppSrc * appsrc, gboolean do_min, guint64 min,
     gboolean do_max, guint64 max)
@@ -1811,10 +1943,21 @@ gst_app_src_push_internal (GstAppSrc * appsrc, GstBuffer * buffer,
     if (priv->is_eos)
       goto eos;
 
+#ifdef TIZEN_FEATURE_UPSTREAM
+    if ((priv->max_bytes && priv->queued_bytes >= priv->max_bytes) ||
+        (priv->max_buffers && priv->queued_buffers >= priv->max_buffers)) {
+      GST_DEBUG_OBJECT (appsrc,
+          "queue filled (queued %" G_GUINT64_FORMAT " bytes, max %"
+          G_GUINT64_FORMAT " bytes, " "queued %" G_GUINT64_FORMAT
+          " buffers, max %" G_GUINT64_FORMAT " buffers",
+          priv->queued_bytes, priv->max_bytes, priv->queued_buffers,
+          priv->max_buffers);
+#else
     if (priv->max_bytes && priv->queued_bytes >= priv->max_bytes) {
       GST_DEBUG_OBJECT (appsrc,
           "queue filled (%" G_GUINT64_FORMAT " >= %" G_GUINT64_FORMAT ")",
           priv->queued_bytes, priv->max_bytes);
+#endif
 
       if (first) {
         gboolean emit;
@@ -1857,12 +2000,18 @@ gst_app_src_push_internal (GstAppSrc * appsrc, GstBuffer * buffer,
       gst_buffer_list_ref (buflist);
     gst_queue_array_push_tail (priv->queue, buflist);
     priv->queued_bytes += gst_buffer_list_calculate_size (buflist);
+#ifdef TIZEN_FEATURE_UPSTREAM
+    priv->queued_buffers += gst_buffer_list_length (buflist);
+#endif
   } else {
     GST_DEBUG_OBJECT (appsrc, "queueing buffer %p", buffer);
     if (!steal_ref)
       gst_buffer_ref (buffer);
     gst_queue_array_push_tail (priv->queue, buffer);
     priv->queued_bytes += gst_buffer_get_size (buffer);
+#ifdef TIZEN_FEATURE_UPSTREAM
+    priv->queued_buffers++;
+#endif
   }
 
   if ((priv->wait_status & STREAM_WAITING))
index 2966a46..2fae10b 100644 (file)
@@ -154,6 +154,14 @@ guint64          gst_app_src_get_max_bytes           (GstAppSrc *appsrc);
 GST_APP_API
 guint64          gst_app_src_get_current_level_bytes (GstAppSrc *appsrc);
 
+#ifdef TIZEN_FEATURE_UPSTREAM
+GST_APP_API
+void             gst_app_src_set_max_buffers           (GstAppSrc *appsrc, guint64 max);
+
+GST_APP_API
+guint64          gst_app_src_get_max_buffers           (GstAppSrc *appsrc);
+#endif
+
 GST_APP_API
 void             gst_app_src_set_latency             (GstAppSrc *appsrc, guint64 min, guint64 max);
 
index 340bd95..9753c78 100644 (file)
@@ -5,7 +5,7 @@
 
 Name:           gst-plugins-base
 Version:        1.16.2
-Release:        11
+Release:        12
 License:        LGPL-2.0+
 Summary:        GStreamer Streaming-Media Framework Plug-Ins
 Url:            http://gstreamer.freedesktop.org/