diff --git a/src/gst/gstpipewirepool.c b/src/gst/gstpipewirepool.c index 6ac132c7f..c1792c958 100644 --- a/src/gst/gstpipewirepool.c +++ b/src/gst/gstpipewirepool.c @@ -33,6 +33,8 @@ #include #include +#include + #include "gstpipewirepool.h" GST_DEBUG_CATEGORY_STATIC (gst_pipewire_pool_debug_category); @@ -115,6 +117,9 @@ void gst_pipewire_pool_wrap_buffer (GstPipeWirePool *pool, struct pw_buffer *b) data->flags = GST_BUFFER_FLAGS (buf); data->b = b; data->buf = buf; + data->crop = spa_buffer_find_meta_data (b->buffer, SPA_META_VideoCrop, sizeof(*data->crop)); + if (data->crop) + gst_buffer_add_video_crop_meta(buf); gst_mini_object_set_qdata (GST_MINI_OBJECT_CAST (buf), pool_data_quark, diff --git a/src/gst/gstpipewirepool.h b/src/gst/gstpipewirepool.h index eb3d8d16e..47c4dc3fa 100644 --- a/src/gst/gstpipewirepool.h +++ b/src/gst/gstpipewirepool.h @@ -57,6 +57,7 @@ struct _GstPipeWirePoolData { struct pw_buffer *b; GstBuffer *buf; gboolean queued; + struct spa_meta_region *crop; }; struct _GstPipeWirePool { diff --git a/src/gst/gstpipewiresink.c b/src/gst/gstpipewiresink.c index 629806ec1..fbb21053c 100644 --- a/src/gst/gstpipewiresink.c +++ b/src/gst/gstpipewiresink.c @@ -47,6 +47,8 @@ #include #include +#include + #include "gstpipewireformat.h" GST_DEBUG_CATEGORY_STATIC (pipewire_sink_debug); @@ -225,7 +227,7 @@ pool_activated (GstPipeWirePool *pool, GstPipeWireSink *sink) guint size; guint min_buffers; guint max_buffers; - const struct spa_pod *port_params[2]; + const struct spa_pod *port_params[3]; struct spa_pod_builder b = { NULL }; uint8_t buffer[1024]; struct spa_pod_frame f; @@ -246,8 +248,8 @@ pool_activated (GstPipeWirePool *pool, GstPipeWireSink *sink) spa_pod_builder_add (&b, SPA_PARAM_BUFFERS_stride, SPA_POD_CHOICE_RANGE_Int(0, 0, INT32_MAX), - SPA_PARAM_BUFFERS_buffers, SPA_POD_CHOICE_RANGE_Int(min_buffers, min_buffers, - max_buffers ? max_buffers : INT32_MAX), + SPA_PARAM_BUFFERS_buffers, SPA_POD_CHOICE_RANGE_Int(SPA_MAX(4u, min_buffers), + SPA_MAX(2u, min_buffers), max_buffers ? max_buffers : INT32_MAX), SPA_PARAM_BUFFERS_align, SPA_POD_Int(16), 0); port_params[0] = spa_pod_builder_pop (&b, &f); @@ -257,9 +259,13 @@ pool_activated (GstPipeWirePool *pool, GstPipeWireSink *sink) SPA_PARAM_META_type, SPA_POD_Int(SPA_META_Header), SPA_PARAM_META_size, SPA_POD_Int(sizeof (struct spa_meta_header))); + port_params[2] = spa_pod_builder_add_object (&b, + SPA_TYPE_OBJECT_ParamMeta, SPA_PARAM_Meta, + SPA_PARAM_META_type, SPA_POD_Int(SPA_META_VideoCrop), + SPA_PARAM_META_size, SPA_POD_Int(sizeof (struct spa_meta_region))); pw_thread_loop_lock (sink->core->loop); - pw_stream_update_params (sink->stream, port_params, 2); + pw_stream_update_params (sink->stream, port_params, 3); pw_thread_loop_unlock (sink->core->loop); } @@ -423,6 +429,15 @@ do_send_buffer (GstPipeWireSink *pwsink, GstBuffer *buffer) data->header->pts = GST_BUFFER_PTS (buffer); data->header->dts_offset = GST_BUFFER_DTS (buffer); } + if (data->crop) { + GstVideoCropMeta *meta = gst_buffer_get_video_crop_meta (buffer); + if (meta) { + data->crop->region.position.x = meta->x; + data->crop->region.position.y = meta->y; + data->crop->region.size.width = meta->width; + data->crop->region.size.height = meta->width; + } + } for (i = 0; i < b->n_datas; i++) { struct spa_data *d = &b->datas[i]; GstMemory *mem = gst_buffer_peek_memory (buffer, i); diff --git a/src/gst/gstpipewiresrc.c b/src/gst/gstpipewiresrc.c index ce1ce08b0..302bd9adf 100644 --- a/src/gst/gstpipewiresrc.c +++ b/src/gst/gstpipewiresrc.c @@ -452,6 +452,7 @@ static GstBuffer *dequeue_buffer(GstPipeWireSrc *pwsrc) GstBuffer *buf; GstPipeWirePoolData *data; struct spa_meta_header *h; + struct spa_meta_region *crop; guint i; b = pw_stream_dequeue_buffer (pwsrc->stream); @@ -482,6 +483,16 @@ static GstBuffer *dequeue_buffer(GstPipeWireSrc *pwsrc) } GST_BUFFER_OFFSET (buf) = h->seq; } + crop = data->crop; + if (crop) { + GstVideoCropMeta *meta = gst_buffer_get_video_crop_meta(buf); + if (meta) { + meta->x = crop->region.position.x; + meta->y = crop->region.position.y; + meta->width = crop->region.size.width; + meta->height = crop->region.size.height; + } + } for (i = 0; i < b->buffer->n_datas; i++) { struct spa_data *d = &b->buffer->datas[i]; GstMemory *mem = gst_buffer_peek_memory (buf, i); @@ -753,7 +764,7 @@ on_param_changed (void *data, uint32_t id, gst_caps_unref (caps); if (res) { - const struct spa_pod *params[2]; + const struct spa_pod *params[3]; struct spa_pod_builder b = { NULL }; uint8_t buffer[512]; uint32_t buffers = CLAMP (16, pwsrc->min_buffers, pwsrc->max_buffers); @@ -773,9 +784,13 @@ on_param_changed (void *data, uint32_t id, SPA_TYPE_OBJECT_ParamMeta, SPA_PARAM_Meta, SPA_PARAM_META_type, SPA_POD_Id(SPA_META_Header), SPA_PARAM_META_size, SPA_POD_Int(sizeof (struct spa_meta_header))); + params[2] = spa_pod_builder_add_object (&b, + SPA_TYPE_OBJECT_ParamMeta, SPA_PARAM_Meta, + SPA_PARAM_META_type, SPA_POD_Id(SPA_META_VideoCrop), + SPA_PARAM_META_size, SPA_POD_Int(sizeof (struct spa_meta_region))); GST_DEBUG_OBJECT (pwsrc, "doing finish format"); - pw_stream_update_params (pwsrc->stream, params, 2); + pw_stream_update_params (pwsrc->stream, params, 3); } else { GST_WARNING_OBJECT (pwsrc, "finish format with error"); pw_stream_set_error (pwsrc->stream, -EINVAL, "unhandled format");