gst: support VideoCrop meta

Convert the VideoCrop metadata to GStreamer metadata.
This commit is contained in:
Wim Taymans 2020-07-31 11:44:46 +02:00
parent 6fd373ac83
commit 5f40bc6d4e
4 changed files with 42 additions and 6 deletions

View file

@ -33,6 +33,8 @@
#include <gst/allocators/gstfdmemory.h> #include <gst/allocators/gstfdmemory.h>
#include <gst/allocators/gstdmabuf.h> #include <gst/allocators/gstdmabuf.h>
#include <gst/video/gstvideometa.h>
#include "gstpipewirepool.h" #include "gstpipewirepool.h"
GST_DEBUG_CATEGORY_STATIC (gst_pipewire_pool_debug_category); 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->flags = GST_BUFFER_FLAGS (buf);
data->b = b; data->b = b;
data->buf = buf; 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), gst_mini_object_set_qdata (GST_MINI_OBJECT_CAST (buf),
pool_data_quark, pool_data_quark,

View file

@ -57,6 +57,7 @@ struct _GstPipeWirePoolData {
struct pw_buffer *b; struct pw_buffer *b;
GstBuffer *buf; GstBuffer *buf;
gboolean queued; gboolean queued;
struct spa_meta_region *crop;
}; };
struct _GstPipeWirePool { struct _GstPipeWirePool {

View file

@ -47,6 +47,8 @@
#include <spa/pod/builder.h> #include <spa/pod/builder.h>
#include <spa/utils/result.h> #include <spa/utils/result.h>
#include <gst/video/video.h>
#include "gstpipewireformat.h" #include "gstpipewireformat.h"
GST_DEBUG_CATEGORY_STATIC (pipewire_sink_debug); GST_DEBUG_CATEGORY_STATIC (pipewire_sink_debug);
@ -225,7 +227,7 @@ pool_activated (GstPipeWirePool *pool, GstPipeWireSink *sink)
guint size; guint size;
guint min_buffers; guint min_buffers;
guint max_buffers; guint max_buffers;
const struct spa_pod *port_params[2]; const struct spa_pod *port_params[3];
struct spa_pod_builder b = { NULL }; struct spa_pod_builder b = { NULL };
uint8_t buffer[1024]; uint8_t buffer[1024];
struct spa_pod_frame f; struct spa_pod_frame f;
@ -246,8 +248,8 @@ pool_activated (GstPipeWirePool *pool, GstPipeWireSink *sink)
spa_pod_builder_add (&b, spa_pod_builder_add (&b,
SPA_PARAM_BUFFERS_stride, SPA_POD_CHOICE_RANGE_Int(0, 0, INT32_MAX), 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, SPA_PARAM_BUFFERS_buffers, SPA_POD_CHOICE_RANGE_Int(SPA_MAX(4u, min_buffers),
max_buffers ? max_buffers : INT32_MAX), SPA_MAX(2u, min_buffers), max_buffers ? max_buffers : INT32_MAX),
SPA_PARAM_BUFFERS_align, SPA_POD_Int(16), SPA_PARAM_BUFFERS_align, SPA_POD_Int(16),
0); 0);
port_params[0] = spa_pod_builder_pop (&b, &f); 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_type, SPA_POD_Int(SPA_META_Header),
SPA_PARAM_META_size, SPA_POD_Int(sizeof (struct 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_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); 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->pts = GST_BUFFER_PTS (buffer);
data->header->dts_offset = GST_BUFFER_DTS (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++) { for (i = 0; i < b->n_datas; i++) {
struct spa_data *d = &b->datas[i]; struct spa_data *d = &b->datas[i];
GstMemory *mem = gst_buffer_peek_memory (buffer, i); GstMemory *mem = gst_buffer_peek_memory (buffer, i);

View file

@ -452,6 +452,7 @@ static GstBuffer *dequeue_buffer(GstPipeWireSrc *pwsrc)
GstBuffer *buf; GstBuffer *buf;
GstPipeWirePoolData *data; GstPipeWirePoolData *data;
struct spa_meta_header *h; struct spa_meta_header *h;
struct spa_meta_region *crop;
guint i; guint i;
b = pw_stream_dequeue_buffer (pwsrc->stream); b = pw_stream_dequeue_buffer (pwsrc->stream);
@ -482,6 +483,16 @@ static GstBuffer *dequeue_buffer(GstPipeWireSrc *pwsrc)
} }
GST_BUFFER_OFFSET (buf) = h->seq; 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++) { for (i = 0; i < b->buffer->n_datas; i++) {
struct spa_data *d = &b->buffer->datas[i]; struct spa_data *d = &b->buffer->datas[i];
GstMemory *mem = gst_buffer_peek_memory (buf, 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); gst_caps_unref (caps);
if (res) { if (res) {
const struct spa_pod *params[2]; const struct spa_pod *params[3];
struct spa_pod_builder b = { NULL }; struct spa_pod_builder b = { NULL };
uint8_t buffer[512]; uint8_t buffer[512];
uint32_t buffers = CLAMP (16, pwsrc->min_buffers, pwsrc->max_buffers); 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_TYPE_OBJECT_ParamMeta, SPA_PARAM_Meta,
SPA_PARAM_META_type, SPA_POD_Id(SPA_META_Header), SPA_PARAM_META_type, SPA_POD_Id(SPA_META_Header),
SPA_PARAM_META_size, SPA_POD_Int(sizeof (struct 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"); GST_DEBUG_OBJECT (pwsrc, "doing finish format");
pw_stream_update_params (pwsrc->stream, params, 2); pw_stream_update_params (pwsrc->stream, params, 3);
} else { } else {
GST_WARNING_OBJECT (pwsrc, "finish format with error"); GST_WARNING_OBJECT (pwsrc, "finish format with error");
pw_stream_set_error (pwsrc->stream, -EINVAL, "unhandled format"); pw_stream_set_error (pwsrc->stream, -EINVAL, "unhandled format");