From 602a94a71a9c6e2cec3611ddd0f6a065dab63368 Mon Sep 17 00:00:00 2001 From: Eunhye Choi Date: Tue, 8 Jun 2021 19:50:26 +0900 Subject: [PATCH] appsrc: add max-buffers property - 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 | 149 ++++++++++++++++++++++++++++++++++++++++ gst-libs/gst/app/gstappsrc.h | 8 +++ packaging/gst-plugins-base.spec | 2 +- 3 files changed, 158 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/app/gstappsrc.c b/gst-libs/gst/app/gstappsrc.c index 66ad05e..4ec26d6 100644 --- a/gst-libs/gst/app/gstappsrc.c +++ b/gst-libs/gst/app/gstappsrc.c @@ -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)) diff --git a/gst-libs/gst/app/gstappsrc.h b/gst-libs/gst/app/gstappsrc.h index 2966a46..2fae10b 100644 --- a/gst-libs/gst/app/gstappsrc.h +++ b/gst-libs/gst/app/gstappsrc.h @@ -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); diff --git a/packaging/gst-plugins-base.spec b/packaging/gst-plugins-base.spec index 340bd95..9753c78 100644 --- a/packaging/gst-plugins-base.spec +++ b/packaging/gst-plugins-base.spec @@ -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/ -- 2.7.4