From fd00d16361d24718e59dbd90ad290e381500eb5c Mon Sep 17 00:00:00 2001 From: Michael Tretter Date: Fri, 20 Mar 2020 17:00:36 +0100 Subject: [PATCH] gst: add properties for limits of negotiated buffers By default, the pipewiresrc tries to negotiate 16 buffers. This value is hard coded in the pipewiresrc. If the buffers are large, this could lead to an undesirably high memory usage. Applications that know about the buffer size and that fewer buffers are sufficient should be able to configure the limits for the number of buffers that are negotiated. Therefore, add the min-buffers and max-buffers properties to the pipewiresrc to enable applications to configure limits for the number of negotiated buffers. --- src/gst/gstpipewiresrc.c | 45 +++++++++++++++++++++++++++++++++++++++- src/gst/gstpipewiresrc.h | 2 ++ 2 files changed, 46 insertions(+), 1 deletion(-) diff --git a/src/gst/gstpipewiresrc.c b/src/gst/gstpipewiresrc.c index 95d262373..d2e9b3213 100644 --- a/src/gst/gstpipewiresrc.c +++ b/src/gst/gstpipewiresrc.c @@ -60,6 +60,8 @@ GST_DEBUG_CATEGORY_STATIC (pipewire_src_debug); #define GST_CAT_DEFAULT pipewire_src_debug #define DEFAULT_ALWAYS_COPY false +#define DEFAULT_MIN_BUFFERS 1 +#define DEFAULT_MAX_BUFFERS INT32_MAX enum { @@ -68,6 +70,8 @@ enum PROP_CLIENT_NAME, PROP_STREAM_PROPERTIES, PROP_ALWAYS_COPY, + PROP_MIN_BUFFERS, + PROP_MAX_BUFFERS, PROP_FD, }; @@ -124,6 +128,14 @@ gst_pipewire_src_set_property (GObject * object, guint prop_id, pwsrc->always_copy = g_value_get_boolean (value); break; + case PROP_MIN_BUFFERS: + pwsrc->min_buffers = g_value_get_int (value); + break; + + case PROP_MAX_BUFFERS: + pwsrc->max_buffers = g_value_get_int (value); + break; + case PROP_FD: pwsrc->fd = g_value_get_int (value); break; @@ -157,6 +169,14 @@ gst_pipewire_src_get_property (GObject * object, guint prop_id, g_value_set_boolean (value, pwsrc->always_copy); break; + case PROP_MIN_BUFFERS: + g_value_set_int (value, pwsrc->min_buffers); + break; + + case PROP_MAX_BUFFERS: + g_value_set_int (value, pwsrc->max_buffers); + break; + case PROP_FD: g_value_set_int (value, pwsrc->fd); break; @@ -282,6 +302,24 @@ gst_pipewire_src_class_init (GstPipeWireSrcClass * klass) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + g_object_class_install_property (gobject_class, + PROP_MIN_BUFFERS, + g_param_spec_int ("min-buffers", + "Min Buffers", + "Minimum number of buffers to negotiate with PipeWire", + 1, G_MAXINT, DEFAULT_MIN_BUFFERS, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property (gobject_class, + PROP_MAX_BUFFERS, + g_param_spec_int ("max-buffers", + "Max Buffers", + "Maximum number of buffers to negotiate with PipeWire", + 1, G_MAXINT, DEFAULT_MAX_BUFFERS, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + g_object_class_install_property (gobject_class, PROP_FD, g_param_spec_int ("fd", @@ -325,6 +363,8 @@ gst_pipewire_src_init (GstPipeWireSrc * src) GST_OBJECT_FLAG_SET (src, GST_ELEMENT_FLAG_PROVIDE_CLOCK); src->always_copy = DEFAULT_ALWAYS_COPY; + src->min_buffers = DEFAULT_MIN_BUFFERS; + src->max_buffers = DEFAULT_MAX_BUFFERS; src->fd = -1; g_queue_init (&src->queue); @@ -699,11 +739,14 @@ on_param_changed (void *data, uint32_t id, const struct spa_pod *params[2]; struct spa_pod_builder b = { NULL }; uint8_t buffer[512]; + uint32_t buffers = buffers = CLAMP (16, pwsrc->min_buffers, pwsrc->max_buffers); spa_pod_builder_init (&b, buffer, sizeof (buffer)); params[0] = spa_pod_builder_add_object (&b, SPA_TYPE_OBJECT_ParamBuffers, SPA_PARAM_Buffers, - SPA_PARAM_BUFFERS_buffers, SPA_POD_CHOICE_RANGE_Int(16, 1, INT32_MAX), + SPA_PARAM_BUFFERS_buffers, SPA_POD_CHOICE_RANGE_Int(buffers, + pwsrc->min_buffers, + pwsrc->max_buffers), SPA_PARAM_BUFFERS_blocks, SPA_POD_CHOICE_RANGE_Int(0, 1, INT32_MAX), SPA_PARAM_BUFFERS_size, SPA_POD_CHOICE_RANGE_Int(0, 0, INT32_MAX), SPA_PARAM_BUFFERS_stride, SPA_POD_CHOICE_RANGE_Int(0, 0, INT32_MAX), diff --git a/src/gst/gstpipewiresrc.h b/src/gst/gstpipewiresrc.h index 02374f6d3..c80e13ee0 100644 --- a/src/gst/gstpipewiresrc.h +++ b/src/gst/gstpipewiresrc.h @@ -61,6 +61,8 @@ struct _GstPipeWireSrc { gchar *path; gchar *client_name; gboolean always_copy; + gint min_buffers; + gint max_buffers; int fd; gboolean negotiated;