va: filter, vpp: add and use GstVaSample struct
authorVíctor Manuel Jáquez Leal <vjaquez@igalia.com>
Sat, 23 Jan 2021 11:53:25 +0000 (12:53 +0100)
committerVíctor Manuel Jáquez Leal <vjaquez@igalia.com>
Sat, 3 Apr 2021 13:47:18 +0000 (15:47 +0200)
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: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/2058>

sys/va/gstvafilter.c
sys/va/gstvafilter.h
sys/va/gstvavpp.c

index d79fa2b..0cec913 100644 (file)
@@ -28,6 +28,7 @@
 
 #include <va/va_drmcommon.h>
 
+#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));
index e747cc2..85886d9 100644 (file)
@@ -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
index 2dc83a7..8937c77 100644 (file)
@@ -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,
+  };
+
+  dst = (GstVaSample) {
+    .buffer = outbuf,
+  };
+  /* *INDENT-ON* */
 
-  if (!gst_va_filter_convert_surface (self->filter, in_surface, out_surface)) {
+  if (!gst_va_filter_convert_surface (self->filter, &src, &dst)) {
     gst_buffer_set_flags (outbuf, GST_BUFFER_FLAG_CORRUPTED);
   }