diff --git a/src/gst/gstpipewirepool.h b/src/gst/gstpipewirepool.h index 3e6c3339a..fb00a100c 100644 --- a/src/gst/gstpipewirepool.h +++ b/src/gst/gstpipewirepool.h @@ -47,6 +47,12 @@ struct _GstPipeWirePool { gboolean paused; }; +enum GstPipeWirePoolMode { + USE_BUFFERPOOL_NO = 0, + USE_BUFFERPOOL_AUTO, + USE_BUFFERPOOL_YES +}; + GstPipeWirePool * gst_pipewire_pool_new (GstPipeWireStream *stream); void gst_pipewire_pool_wrap_buffer (GstPipeWirePool *pool, struct pw_buffer *buffer); diff --git a/src/gst/gstpipewiresink.c b/src/gst/gstpipewiresink.c index cd245d296..7423f1158 100644 --- a/src/gst/gstpipewiresink.c +++ b/src/gst/gstpipewiresink.c @@ -38,6 +38,7 @@ GST_DEBUG_CATEGORY_STATIC (pipewire_sink_debug); #define DEFAULT_PROP_MODE GST_PIPEWIRE_SINK_MODE_DEFAULT #define DEFAULT_PROP_SLAVE_METHOD GST_PIPEWIRE_SINK_SLAVE_METHOD_NONE +#define DEFAULT_PROP_USE_BUFFERPOOL USE_BUFFERPOOL_AUTO #define MIN_BUFFERS 8u @@ -51,7 +52,8 @@ enum PROP_STREAM_PROPERTIES, PROP_MODE, PROP_FD, - PROP_SLAVE_METHOD + PROP_SLAVE_METHOD, + PROP_USE_BUFFERPOOL, }; GType @@ -164,7 +166,9 @@ gst_pipewire_sink_propose_allocation (GstBaseSink * bsink, GstQuery * query) { GstPipeWireSink *pwsink = GST_PIPEWIRE_SINK (bsink); - gst_query_add_allocation_pool (query, GST_BUFFER_POOL_CAST (pwsink->stream->pool), 0, 0, 0); + if (pwsink->use_bufferpool != USE_BUFFERPOOL_NO) + gst_query_add_allocation_pool (query, GST_BUFFER_POOL_CAST (pwsink->stream->pool), 0, 0, 0); + gst_query_add_allocation_meta (query, GST_VIDEO_META_API_TYPE, NULL); return TRUE; } @@ -259,6 +263,14 @@ gst_pipewire_sink_class_init (GstPipeWireSinkClass * klass) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + g_object_class_install_property (gobject_class, + PROP_USE_BUFFERPOOL, + g_param_spec_boolean ("use-bufferpool", + "Use bufferpool", + "Use bufferpool (default: true for video, false for audio)", + DEFAULT_PROP_USE_BUFFERPOOL, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); gstelement_class->provide_clock = gst_pipewire_sink_provide_clock; gstelement_class->change_state = gst_pipewire_sink_change_state; @@ -343,6 +355,7 @@ gst_pipewire_sink_init (GstPipeWireSink * sink) sink->stream = gst_pipewire_stream_new (GST_ELEMENT (sink)); sink->mode = DEFAULT_PROP_MODE; + sink->use_bufferpool = DEFAULT_PROP_USE_BUFFERPOOL; GST_OBJECT_FLAG_SET (sink, GST_ELEMENT_FLAG_PROVIDE_CLOCK); @@ -448,6 +461,13 @@ gst_pipewire_sink_set_property (GObject * object, guint prop_id, pwsink->slave_method = g_value_get_enum (value); break; + case PROP_USE_BUFFERPOOL: + if(g_value_get_boolean (value)) + pwsink->use_bufferpool = USE_BUFFERPOOL_YES; + else + pwsink->use_bufferpool = USE_BUFFERPOOL_NO; + break; + default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -493,6 +513,10 @@ gst_pipewire_sink_get_property (GObject * object, guint prop_id, g_value_set_enum (value, pwsink->slave_method); break; + case PROP_USE_BUFFERPOOL: + g_value_set_boolean (value, !!pwsink->use_bufferpool); + break; + default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -724,6 +748,10 @@ gst_pipewire_sink_setcaps (GstBaseSink * bsink, GstCaps * caps) gst_structure_get_int (s, "rate", &rate); pwsink->rate = rate; pwsink->rate_match = true; + + /* Don't provide bufferpool for audio if not requested by the application/user */ + if (pwsink->use_bufferpool != USE_BUFFERPOOL_YES) + pwsink->use_bufferpool = USE_BUFFERPOOL_NO; } else { pwsink->rate = rate = 0; pwsink->rate_match = false; diff --git a/src/gst/gstpipewiresink.h b/src/gst/gstpipewiresink.h index cac5bb93f..968c38513 100644 --- a/src/gst/gstpipewiresink.h +++ b/src/gst/gstpipewiresink.h @@ -63,6 +63,7 @@ struct _GstPipeWireSink { /*< private >*/ GstPipeWireStream *stream; + gboolean use_bufferpool; /* video state */ gboolean negotiated; diff --git a/src/gst/gstpipewiresrc.c b/src/gst/gstpipewiresrc.c index 69c8e3b26..1cd049418 100644 --- a/src/gst/gstpipewiresrc.c +++ b/src/gst/gstpipewiresrc.c @@ -46,6 +46,7 @@ GST_DEBUG_CATEGORY_STATIC (pipewire_src_debug); #define DEFAULT_RESEND_LAST false #define DEFAULT_KEEPALIVE_TIME 0 #define DEFAULT_AUTOCONNECT true +#define DEFAULT_USE_BUFFERPOOL USE_BUFFERPOOL_AUTO enum { @@ -62,6 +63,7 @@ enum PROP_RESEND_LAST, PROP_KEEPALIVE_TIME, PROP_AUTOCONNECT, + PROP_USE_BUFFERPOOL, }; @@ -130,7 +132,11 @@ gst_pipewire_src_set_property (GObject * object, guint prop_id, break; case PROP_ALWAYS_COPY: - pwsrc->always_copy = g_value_get_boolean (value); + /* don't provide buffer if always copy*/ + if (g_value_get_boolean (value)) + pwsrc->use_bufferpool = USE_BUFFERPOOL_NO; + else + pwsrc->use_bufferpool = USE_BUFFERPOOL_YES; break; case PROP_MIN_BUFFERS: @@ -157,6 +163,13 @@ gst_pipewire_src_set_property (GObject * object, guint prop_id, pwsrc->autoconnect = g_value_get_boolean (value); break; + case PROP_USE_BUFFERPOOL: + if(g_value_get_boolean (value)) + pwsrc->use_bufferpool = USE_BUFFERPOOL_YES; + else + pwsrc->use_bufferpool = USE_BUFFERPOOL_NO; + break; + default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -191,7 +204,7 @@ gst_pipewire_src_get_property (GObject * object, guint prop_id, break; case PROP_ALWAYS_COPY: - g_value_set_boolean (value, pwsrc->always_copy); + g_value_set_boolean (value, !pwsrc->use_bufferpool); break; case PROP_MIN_BUFFERS: @@ -218,6 +231,10 @@ gst_pipewire_src_get_property (GObject * object, guint prop_id, g_value_set_boolean (value, pwsrc->autoconnect); break; + case PROP_USE_BUFFERPOOL: + g_value_set_boolean (value, !!pwsrc->use_bufferpool); + break; + default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -331,7 +348,8 @@ gst_pipewire_src_class_init (GstPipeWireSrcClass * klass) "Always copy the buffer and data", DEFAULT_ALWAYS_COPY, G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS)); + G_PARAM_STATIC_STRINGS | + G_PARAM_DEPRECATED)); g_object_class_install_property (gobject_class, PROP_MIN_BUFFERS, @@ -387,6 +405,15 @@ gst_pipewire_src_class_init (GstPipeWireSrcClass * klass) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + g_object_class_install_property (gobject_class, + PROP_USE_BUFFERPOOL, + g_param_spec_boolean ("use-bufferpool", + "Use bufferpool", + "Use bufferpool (default: true for video, false for audio)", + DEFAULT_USE_BUFFERPOOL, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + gstelement_class->provide_clock = gst_pipewire_src_provide_clock; gstelement_class->change_state = gst_pipewire_src_change_state; gstelement_class->send_event = gst_pipewire_src_send_event; @@ -427,7 +454,7 @@ gst_pipewire_src_init (GstPipeWireSrc * src) src->stream = gst_pipewire_stream_new (GST_ELEMENT (src)); - src->always_copy = DEFAULT_ALWAYS_COPY; + src->use_bufferpool = DEFAULT_USE_BUFFERPOOL; src->min_buffers = DEFAULT_MIN_BUFFERS; src->max_buffers = DEFAULT_MAX_BUFFERS; src->resend_last = DEFAULT_RESEND_LAST; @@ -665,7 +692,7 @@ static GstBuffer *dequeue_buffer(GstPipeWireSrc *pwsrc) GstMemory *pmem = gst_buffer_peek_memory (data->buf, i); if (pmem) { GstMemory *mem; - if (!pwsrc->always_copy) + if (pwsrc->use_bufferpool != USE_BUFFERPOOL_NO) mem = gst_memory_share (pmem, d->chunk->offset, d->chunk->size); else mem = gst_memory_copy (pmem, d->chunk->offset, d->chunk->size); @@ -676,7 +703,7 @@ static GstBuffer *dequeue_buffer(GstPipeWireSrc *pwsrc) GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_CORRUPTED); } } - if (!pwsrc->always_copy) + if (pwsrc->use_bufferpool != USE_BUFFERPOOL_NO) gst_buffer_add_parent_buffer_meta (buf, data->buf); gst_buffer_unref (data->buf); @@ -1104,6 +1131,10 @@ handle_format_change (GstPipeWireSrc *pwsrc, } else { pwsrc->negotiated = FALSE; pwsrc->is_video = FALSE; + + /* Don't provide bufferpool for audio if not requested by the application/user */ + if (pwsrc->use_bufferpool != USE_BUFFERPOOL_YES) + pwsrc->use_bufferpool = USE_BUFFERPOOL_NO; } if (pwsrc->caps) { diff --git a/src/gst/gstpipewiresrc.h b/src/gst/gstpipewiresrc.h index d8533c78a..d5728cdc9 100644 --- a/src/gst/gstpipewiresrc.h +++ b/src/gst/gstpipewiresrc.h @@ -36,7 +36,7 @@ struct _GstPipeWireSrc { GstPipeWireStream *stream; /*< private >*/ - gboolean always_copy; + gint use_bufferpool; gint min_buffers; gint max_buffers; gboolean resend_last;