From c770469a8a58043f22c86163835c5c0647e626ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Sat, 23 Jan 2021 12:53:25 +0100 Subject: [PATCH] va: filter, vpp: add and use GstVaSample struct This new struct describes the input and output GstBuffers to post-process, including VA flags. It also contains the VASurfaceID and VARectangle, but those are private, completed inside GstVaFilter. It is used for pass arguments to gst_va_filter_convert_surface() function. Part-of: --- sys/va/gstvafilter.c | 56 ++++++++++++++++++++++++++++---------------- sys/va/gstvafilter.h | 15 ++++++++++-- sys/va/gstvavpp.c | 15 ++++++++---- 3 files changed, 60 insertions(+), 26 deletions(-) diff --git a/sys/va/gstvafilter.c b/sys/va/gstvafilter.c index d79fa2bbb4..0cec913552 100644 --- a/sys/va/gstvafilter.c +++ b/sys/va/gstvafilter.c @@ -28,6 +28,7 @@ #include +#include "gstvaallocator.h" #include "gstvacaps.h" #include "gstvavideoformat.h" @@ -1234,8 +1235,25 @@ gst_va_filter_drop_filter_buffers (GstVaFilter * self) } static gboolean -_create_pipeline_buffer (GstVaFilter * self, VASurfaceID surface, - VARectangle * src_rect, VARectangle * dst_rect, VABufferID * buffer) +_fill_va_sample (GstVaFilter * self, GstVaSample * sample, + GstPadDirection direction) +{ + sample->surface = gst_va_buffer_get_surface (sample->buffer); + if (sample->surface == VA_INVALID_ID) + return FALSE; + + /* TODO: handle GstVideoCropMeta */ + GST_OBJECT_LOCK (self); + sample->rect = (direction == GST_PAD_SRC) ? + self->output_region : self->input_region; + GST_OBJECT_UNLOCK (self); + + return TRUE; +} + +static gboolean +_create_pipeline_buffer (GstVaFilter * self, GstVaSample * src, + GstVaSample * dst, VABufferID * buffer) { VADisplay dpy; VAStatus status; @@ -1252,16 +1270,18 @@ _create_pipeline_buffer (GstVaFilter * self, VASurfaceID surface, } params = (VAProcPipelineParameterBuffer) { - .surface = surface, - .surface_region = src_rect, + .surface = src->surface, + .surface_region = &src->rect, .surface_color_standard = self->input_color_standard, - .output_region = dst_rect, + .output_region = &dst->rect, .output_background_color = 0xff000000, /* ARGB black */ .output_color_standard = self->output_color_standard, .filters = filters, .num_filters = num_filters, .rotation_state = self->rotation, .mirror_state = self->mirror, + .input_surface_flag = src->flags, + .output_surface_flag = dst->flags, .input_color_properties = self->input_color_properties, .output_color_properties = self->output_color_properties, }; @@ -1286,31 +1306,28 @@ _create_pipeline_buffer (GstVaFilter * self, VASurfaceID surface, } gboolean -gst_va_filter_convert_surface (GstVaFilter * self, VASurfaceID in_surface, - VASurfaceID out_surface) +gst_va_filter_convert_surface (GstVaFilter * self, GstVaSample * src, + GstVaSample * dst) { - VABufferID buffer; + VABufferID buffer, *filters = NULL; VADisplay dpy; VAProcPipelineCaps pipeline_caps = { 0, }; - VARectangle src_rect; - VARectangle dst_rect; VAStatus status; - VABufferID *filters = NULL; - guint32 num_filters = 0; gboolean ret = FALSE; + guint32 num_filters = 0; g_return_val_if_fail (GST_IS_VA_FILTER (self), FALSE); - g_return_val_if_fail (in_surface != VA_INVALID_ID - && out_surface != VA_INVALID_ID, FALSE); + g_return_val_if_fail (src && GST_IS_BUFFER (src->buffer), FALSE); + g_return_val_if_fail (dst && GST_IS_BUFFER (dst->buffer), FALSE); if (!gst_va_filter_is_open (self)) return FALSE; - GST_TRACE_OBJECT (self, "Processing %#x", in_surface); + if (!(_fill_va_sample (self, src, GST_PAD_SINK) + && _fill_va_sample (self, dst, GST_PAD_SRC))) + return FALSE; GST_OBJECT_LOCK (self); - src_rect = self->input_region; - dst_rect = self->output_region; if (self->filters) { g_array_ref (self->filters); @@ -1331,12 +1348,11 @@ gst_va_filter_convert_surface (GstVaFilter * self, VASurfaceID in_surface, return FALSE; } - if (!_create_pipeline_buffer (self, in_surface, &src_rect, &dst_rect, - &buffer)) + if (!_create_pipeline_buffer (self, src, dst, &buffer)) return FALSE; gst_va_display_lock (self->display); - status = vaBeginPicture (dpy, self->context, out_surface); + status = vaBeginPicture (dpy, self->context, dst->surface); gst_va_display_unlock (self->display); if (status != VA_STATUS_SUCCESS) { GST_ERROR_OBJECT (self, "vaBeginPicture: %s", vaErrorStr (status)); diff --git a/sys/va/gstvafilter.h b/sys/va/gstvafilter.h index e747cc2dd8..85886d994e 100644 --- a/sys/va/gstvafilter.h +++ b/sys/va/gstvafilter.h @@ -46,6 +46,17 @@ enum { GST_VA_FILTER_PROP_LAST }; +typedef struct _GstVaSample GstVaSample; +struct _GstVaSample +{ + GstBuffer *buffer; + guint32 flags; + + /*< private >*/ + VASurfaceID surface; + VARectangle rect; +}; + GstVaFilter * gst_va_filter_new (GstVaDisplay * display); gboolean gst_va_filter_open (GstVaFilter * self); gboolean gst_va_filter_close (GstVaFilter * self); @@ -72,7 +83,7 @@ gboolean gst_va_filter_add_filter_buffer (GstVaFilter * self, guint num); gboolean gst_va_filter_drop_filter_buffers (GstVaFilter * self); gboolean gst_va_filter_convert_surface (GstVaFilter * self, - VASurfaceID in_surface, - VASurfaceID out_surface); + GstVaSample * src, + GstVaSample * dest); G_END_DECLS diff --git a/sys/va/gstvavpp.c b/sys/va/gstvavpp.c index 2dc83a79f1..8937c77f4f 100644 --- a/sys/va/gstvavpp.c +++ b/sys/va/gstvavpp.c @@ -1235,7 +1235,7 @@ gst_va_vpp_transform (GstBaseTransform * trans, GstBuffer * inbuf, GstVaVpp *self = GST_VA_VPP (trans); GstBuffer *buf = NULL; GstFlowReturn res = GST_FLOW_OK; - VASurfaceID in_surface, out_surface; + GstVaSample src, dst; if (G_UNLIKELY (!self->negotiated)) goto unknown_format; @@ -1244,10 +1244,17 @@ gst_va_vpp_transform (GstBaseTransform * trans, GstBuffer * inbuf, if (res != GST_FLOW_OK) return res; - in_surface = gst_va_buffer_get_surface (buf); - out_surface = gst_va_buffer_get_surface (outbuf); + /* *INDENT-OFF* */ + src = (GstVaSample) { + .buffer = buf, + }; - if (!gst_va_filter_convert_surface (self->filter, in_surface, out_surface)) { + dst = (GstVaSample) { + .buffer = outbuf, + }; + /* *INDENT-ON* */ + + if (!gst_va_filter_convert_surface (self->filter, &src, &dst)) { gst_buffer_set_flags (outbuf, GST_BUFFER_FLAG_CORRUPTED); }