libs: va: add VA allocator parameter for derived images usage.
authorVíctor Manuel Jáquez Leal <vjaquez@igalia.com>
Tue, 29 Mar 2022 12:52:33 +0000 (14:52 +0200)
committerVíctor Manuel Jáquez Leal <vjaquez@igalia.com>
Thu, 31 Mar 2022 14:14:45 +0000 (14:14 +0000)
Added GstVaFeature enum type, and new parameter for VA allocator's
set_format() and get_format(). Also added a new parameter in VA pool
gst_va_pool_new_with_config() and
gst_buffer_pool_config_set_va_allocation_params().

This new parameter will define if derived images will by used for
buffer mapping.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/2057>

subprojects/gst-plugins-bad/gst-libs/gst/va/gstva.h
subprojects/gst-plugins-bad/gst-libs/gst/va/gstvaallocator.c
subprojects/gst-plugins-bad/gst-libs/gst/va/gstvaallocator.h
subprojects/gst-plugins-bad/gst-libs/gst/va/gstvapool.c
subprojects/gst-plugins-bad/gst-libs/gst/va/gstvapool.h
subprojects/gst-plugins-bad/gst-libs/gst/va/meson.build
subprojects/gst-plugins-bad/sys/va/gstvabasedec.c
subprojects/gst-plugins-bad/sys/va/gstvabasetransform.c
subprojects/gst-plugins-bad/sys/va/gstvaencoder.c
subprojects/gst-plugins-bad/sys/va/gstvah264enc.c

index e9c08eb..b3c4f5c 100644 (file)
 #pragma message ("You can define GST_USE_UNSTABLE_API to avoid this warning.")
 #endif
 
+typedef enum
+{
+  GST_VA_FEATURE_DISABLED,
+  GST_VA_FEATURE_ENABLED,
+  GST_VA_FEATURE_AUTO,
+} GstVaFeature;
+
 #include <gst/va/va-prelude.h>
+#include <gst/va/va-enumtypes.h>
 #include <gst/va/gstvadisplay.h>
 #include <gst/va/gstvadisplay_drm.h>
 #include <gst/va/gstvadisplay_wrapped.h>
index 8d380e8..b4d2134 100644 (file)
@@ -926,6 +926,7 @@ struct _GstVaAllocator
 
   GstVaDisplay *display;
 
+  GstVaFeature feat_use_derived;
   gboolean use_derived;
   GArray *surface_formats;
 
@@ -1088,7 +1089,8 @@ _update_image_info (GstVaAllocator * va_allocator)
       GST_VIDEO_INFO_HEIGHT (&va_allocator->info));
 
   /* Try derived first, but different formats can never derive */
-  if (va_allocator->surface_format == va_allocator->img_format) {
+  if (va_allocator->feat_use_derived != GST_VA_FEATURE_DISABLED
+      && va_allocator->surface_format == va_allocator->img_format) {
     if (va_get_derive_image (va_allocator->display, surface, &image)) {
       va_allocator->use_derived = TRUE;
       va_allocator->derived_info = va_allocator->info;
@@ -1098,6 +1100,12 @@ _update_image_info (GstVaAllocator * va_allocator)
     image.image_id = VA_INVALID_ID;     /* reset it */
   }
 
+  if (va_allocator->feat_use_derived == GST_VA_FEATURE_ENABLED
+      && !va_allocator->use_derived) {
+    GST_WARNING_OBJECT (va_allocator, "Derived images are disabled.");
+    va_allocator->feat_use_derived = GST_VA_FEATURE_DISABLED;
+  }
+
   /* Then we try to create a image. */
   if (!va_create_image (va_allocator->display, va_allocator->img_format,
           GST_VIDEO_INFO_WIDTH (&va_allocator->info),
@@ -1146,30 +1154,36 @@ _va_map_unlocked (GstVaMemory * mem, GstMapFlags flags)
     goto success;
   }
 
-  switch (gst_va_display_get_implementation (display)) {
-    case GST_VA_IMPLEMENTATION_INTEL_IHD:
-      /* On Gen7+ Intel graphics the memory is mappable but not
-       * cached, so normal memcpy() access is very slow to read, but
-       * it's ok for writing. So let's assume that users won't prefer
-       * direct-mapped memory if they request read access. */
-      use_derived = va_allocator->use_derived && !(flags & GST_MAP_READ);
-      break;
-    case GST_VA_IMPLEMENTATION_INTEL_I965:
-      /* YUV derived images are tiled, so writing them is also
-       * problematic */
-      use_derived = va_allocator->use_derived && !((flags & GST_MAP_READ)
-          || ((flags & GST_MAP_WRITE)
-              && GST_VIDEO_INFO_IS_YUV (&va_allocator->derived_info)));
-      break;
-    case GST_VA_IMPLEMENTATION_MESA_GALLIUM:
-      /* Reading RGB derived images, with non-standard resolutions,
-       * looks like tiled too. TODO(victor): fill a bug in Mesa. */
-      use_derived = va_allocator->use_derived && !((flags & GST_MAP_READ)
-          && GST_VIDEO_INFO_IS_RGB (&va_allocator->derived_info));
-      break;
-    default:
-      use_derived = va_allocator->use_derived;
-      break;
+  if (va_allocator->feat_use_derived == GST_VA_FEATURE_ENABLED) {
+    use_derived = TRUE;
+  } else if (va_allocator->feat_use_derived == GST_VA_FEATURE_DISABLED) {
+    use_derived = FALSE;
+  } else {
+    switch (gst_va_display_get_implementation (display)) {
+      case GST_VA_IMPLEMENTATION_INTEL_IHD:
+        /* On Gen7+ Intel graphics the memory is mappable but not
+         * cached, so normal memcpy() access is very slow to read, but
+         * it's ok for writing. So let's assume that users won't prefer
+         * direct-mapped memory if they request read access. */
+        use_derived = va_allocator->use_derived && !(flags & GST_MAP_READ);
+        break;
+      case GST_VA_IMPLEMENTATION_INTEL_I965:
+        /* YUV derived images are tiled, so writing them is also
+         * problematic */
+        use_derived = va_allocator->use_derived && !((flags & GST_MAP_READ)
+            || ((flags & GST_MAP_WRITE)
+                && GST_VIDEO_INFO_IS_YUV (&va_allocator->derived_info)));
+        break;
+      case GST_VA_IMPLEMENTATION_MESA_GALLIUM:
+        /* Reading RGB derived images, with non-standard resolutions,
+         * looks like tiled too. TODO(victor): fill a bug in Mesa. */
+        use_derived = va_allocator->use_derived && !((flags & GST_MAP_READ)
+            && GST_VIDEO_INFO_IS_RGB (&va_allocator->derived_info));
+        break;
+      default:
+        use_derived = va_allocator->use_derived;
+        break;
+    }
   }
   if (use_derived)
     info = &va_allocator->derived_info;
@@ -1373,6 +1387,8 @@ gst_va_allocator_init (GstVaAllocator * self)
 
   gst_va_memory_pool_init (&self->pool);
 
+  self->feat_use_derived = GST_VA_FEATURE_AUTO;
+
   GST_OBJECT_FLAG_SET (self, GST_ALLOCATOR_FLAG_CUSTOM_ALLOC);
 }
 
@@ -1556,7 +1572,7 @@ gst_va_allocator_try (GstAllocator * allocator)
 
 gboolean
 gst_va_allocator_set_format (GstAllocator * allocator, GstVideoInfo * info,
-    guint usage_hint)
+    guint usage_hint, GstVaFeature use_derived)
 {
   GstVaAllocator *self;
   gboolean ret;
@@ -1570,7 +1586,8 @@ gst_va_allocator_set_format (GstAllocator * allocator, GstVideoInfo * info,
     if (GST_VIDEO_INFO_FORMAT (info) == GST_VIDEO_INFO_FORMAT (&self->info)
         && GST_VIDEO_INFO_WIDTH (info) == GST_VIDEO_INFO_WIDTH (&self->info)
         && GST_VIDEO_INFO_HEIGHT (info) == GST_VIDEO_INFO_HEIGHT (&self->info)
-        && usage_hint == self->usage_hint) {
+        && usage_hint == self->usage_hint
+        && use_derived == self->feat_use_derived) {
       *info = self->info;       /* update callee info (offset & stride) */
       return TRUE;
     }
@@ -1578,6 +1595,7 @@ gst_va_allocator_set_format (GstAllocator * allocator, GstVideoInfo * info,
   }
 
   self->usage_hint = usage_hint;
+  self->feat_use_derived = use_derived;
   self->info = *info;
 
   g_clear_pointer (&self->copy, gst_va_surface_copy_free);
@@ -1591,7 +1609,7 @@ gst_va_allocator_set_format (GstAllocator * allocator, GstVideoInfo * info,
 
 gboolean
 gst_va_allocator_get_format (GstAllocator * allocator, GstVideoInfo * info,
-    guint * usage_hint)
+    guint * usage_hint, GstVaFeature * use_derived)
 {
   GstVaAllocator *self;
 
@@ -1605,6 +1623,8 @@ gst_va_allocator_get_format (GstAllocator * allocator, GstVideoInfo * info,
     *info = self->info;
   if (usage_hint)
     *usage_hint = self->usage_hint;
+  if (use_derived)
+    *use_derived = self->feat_use_derived;
 
   return TRUE;
 }
index afd55a1..79f84c0 100644 (file)
@@ -94,11 +94,13 @@ void                  gst_va_allocator_flush              (GstAllocator * alloca
 GST_VA_API
 gboolean              gst_va_allocator_set_format         (GstAllocator * allocator,
                                                            GstVideoInfo * info,
-                                                           guint usage_hint);
+                                                           guint usage_hint,
+                                                          GstVaFeature use_derived);
 GST_VA_API
 gboolean              gst_va_allocator_get_format         (GstAllocator * allocator,
                                                            GstVideoInfo * info,
-                                                           guint * usage_hint);
+                                                           guint * usage_hint,
+                                                          GstVaFeature * use_derived);
 
 GST_VA_API
 VASurfaceID           gst_va_memory_get_surface           (GstMemory * mem);
index 8c985c7..792e2c5 100644 (file)
@@ -65,10 +65,17 @@ gst_va_pool_get_options (GstBufferPool * pool)
 
 static inline gboolean
 gst_buffer_pool_config_get_va_allocation_params (GstStructure * config,
-    guint32 * usage_hint)
+    guint32 * usage_hint, GstVaFeature * use_derived)
 {
-  if (!gst_structure_get (config, "usage-hint", G_TYPE_UINT, usage_hint, NULL))
+  if (!gst_structure_get (config, "usage-hint", G_TYPE_UINT, usage_hint, NULL)) {
     *usage_hint = VA_SURFACE_ATTRIB_USAGE_HINT_GENERIC;
+  }
+
+  if (!gst_structure_get (config, "use-derived", GST_TYPE_VA_FEATURE,
+          use_derived, NULL)) {
+    *use_derived = GST_VA_FEATURE_AUTO;
+  }
+
 
   return TRUE;
 }
@@ -84,6 +91,7 @@ gst_va_pool_set_config (GstBufferPool * pool, GstStructure * config)
   gint width, height;
   guint i, min_buffers, max_buffers;
   guint32 usage_hint;
+  GstVaFeature use_derived;
   gboolean has_alignment;
 
   if (!gst_buffer_pool_config_get_params (config, &caps, NULL, &min_buffers,
@@ -103,7 +111,8 @@ gst_va_pool_set_config (GstBufferPool * pool, GstStructure * config)
               || GST_IS_VA_ALLOCATOR (allocator))))
     goto wrong_config;
 
-  if (!gst_buffer_pool_config_get_va_allocation_params (config, &usage_hint))
+  if (!gst_buffer_pool_config_get_va_allocation_params (config, &usage_hint,
+          &use_derived))
     goto wrong_config;
 
   width = GST_VIDEO_INFO_WIDTH (&caps_info);
@@ -141,7 +150,8 @@ gst_va_pool_set_config (GstBufferPool * pool, GstStructure * config)
             usage_hint))
       goto failed_allocator;
   } else if (GST_IS_VA_ALLOCATOR (allocator)) {
-    if (!gst_va_allocator_set_format (allocator, &alloc_info, usage_hint))
+    if (!gst_va_allocator_set_format (allocator, &alloc_info, usage_hint,
+            use_derived))
       goto failed_allocator;
   }
 
@@ -338,9 +348,10 @@ gst_va_pool_new (void)
 
 void
 gst_buffer_pool_config_set_va_allocation_params (GstStructure * config,
-    guint usage_hint)
+    guint usage_hint, GstVaFeature use_derived)
 {
-  gst_structure_set (config, "usage-hint", G_TYPE_UINT, usage_hint, NULL);
+  gst_structure_set (config, "usage-hint", G_TYPE_UINT, usage_hint,
+      "use-derived", GST_TYPE_VA_FEATURE, use_derived, NULL);
 }
 
 gboolean
@@ -354,8 +365,8 @@ gst_va_pool_requires_video_meta (GstBufferPool * pool)
 
 GstBufferPool *
 gst_va_pool_new_with_config (GstCaps * caps, guint size, guint min_buffers,
-    guint max_buffers, guint usage_hint, GstAllocator * allocator,
-    GstAllocationParams * alloc_params)
+    guint max_buffers, guint usage_hint, GstVaFeature use_derived,
+    GstAllocator * allocator, GstAllocationParams * alloc_params)
 {
   GstBufferPool *pool;
   GstStructure *config;
@@ -365,7 +376,8 @@ gst_va_pool_new_with_config (GstCaps * caps, guint size, guint min_buffers,
   config = gst_buffer_pool_get_config (pool);
   gst_buffer_pool_config_set_params (config, caps, size, min_buffers,
       max_buffers);
-  gst_buffer_pool_config_set_va_allocation_params (config, usage_hint);
+  gst_buffer_pool_config_set_va_allocation_params (config, usage_hint,
+      use_derived);
   gst_buffer_pool_config_set_allocator (config, allocator, alloc_params);
   gst_buffer_pool_config_add_option (config, GST_BUFFER_POOL_OPTION_VIDEO_META);
 
index 6f096b2..1531343 100644 (file)
@@ -40,13 +40,15 @@ GST_VA_API
 gboolean             gst_va_pool_requires_video_meta      (GstBufferPool * pool);
 GST_VA_API
 void                 gst_buffer_pool_config_set_va_allocation_params (GstStructure * config,
-                                                                      guint usage_hint);
+                                                                      guint usage_hint,
+                                                                     GstVaFeature use_derived);
 GST_VA_API
 GstBufferPool *      gst_va_pool_new_with_config          (GstCaps * caps,
                                                            guint size,
                                                            guint min_buffers,
                                                            guint max_buffers,
                                                            guint usage_hint,
+                                                          GstVaFeature use_derived,
                                                            GstAllocator * allocator,
                                                            GstAllocationParams * alloc_params);
 
index 8d5ee3a..d2d47c5 100644 (file)
@@ -42,8 +42,15 @@ endif
 libdrm_dep = dependency('libdrm', required: false, fallback: ['libdrm', 'ext_libdrm'])
 cdata.set10('HAVE_LIBDRM', libdrm_dep.found())
 
+va_enums = gnome.mkenums_simple('va-enumtypes',
+  sources: ['gstva.h'],
+  decorator: 'GST_VA_API',
+  header_prefix: '#include <gst/va/va-prelude.h>',
+  body_prefix: '#ifdef HAVE_CONFIG_H\n#include "config.h"\n#endif',
+  install_header: false)
+
 gstva = library('gstva-' + api_version,
-  va_sources,
+  va_sources, va_enums,
   c_args : gst_plugins_bad_args + ['-DGST_USE_UNSTABLE_API', '-DBUILDING_GST_VA', '-DG_LOG_DOMAIN="GStreamer-VA"'],
   include_directories : [configinc, libsinc],
   version : libversion,
index ccdcf13..662ad62 100644 (file)
@@ -351,7 +351,8 @@ _decide_allocation_for_video_crop (GstVideoDecoder * decoder,
     gst_buffer_pool_config_add_option (other_config,
         GST_BUFFER_POOL_OPTION_VIDEO_META);
 
-    gst_buffer_pool_config_set_va_allocation_params (other_config, 0);
+    gst_buffer_pool_config_set_va_allocation_params (other_config, 0,
+        GST_VA_FEATURE_AUTO);
 
     if (!gst_buffer_pool_set_config (other_pool, other_config)) {
       ret = FALSE;
@@ -391,7 +392,7 @@ _decide_allocation_for_video_crop (GstVideoDecoder * decoder,
     }
 
     gst_buffer_pool_config_set_va_allocation_params (config,
-        VA_SURFACE_ATTRIB_USAGE_HINT_DECODER);
+        VA_SURFACE_ATTRIB_USAGE_HINT_DECODER, GST_VA_FEATURE_AUTO);
 
     if (!gst_buffer_pool_set_config (pool, config)) {
       ret = FALSE;
@@ -566,7 +567,7 @@ gst_va_base_dec_decide_allocation (GstVideoDecoder * decoder, GstQuery * query)
     }
 
     gst_buffer_pool_config_set_va_allocation_params (config,
-        VA_SURFACE_ATTRIB_USAGE_HINT_DECODER);
+        VA_SURFACE_ATTRIB_USAGE_HINT_DECODER, GST_VA_FEATURE_AUTO);
 
     if (!gst_buffer_pool_set_config (pool, config)) {
       ret = FALSE;
index 68bdf1c..cd7f927 100644 (file)
@@ -261,7 +261,7 @@ gst_va_base_transform_propose_allocation (GstBaseTransform * trans,
   }
 
   pool = gst_va_pool_new_with_config (caps, size, 1 + self->extra_min_buffers,
-      0, usage_hint, allocator, &params);
+      0, usage_hint, GST_VA_FEATURE_AUTO, allocator, &params);
   if (!pool) {
     gst_object_unref (allocator);
     goto config_failed;
@@ -392,7 +392,8 @@ gst_va_base_transform_decide_allocation (GstBaseTransform * trans,
   gst_buffer_pool_config_set_allocator (config, allocator, &params);
   gst_buffer_pool_config_add_option (config, GST_BUFFER_POOL_OPTION_VIDEO_META);
   gst_buffer_pool_config_set_params (config, outcaps, size, min, max);
-  gst_buffer_pool_config_set_va_allocation_params (config, usage_hint);
+  gst_buffer_pool_config_set_va_allocation_params (config, usage_hint,
+      GST_VA_FEATURE_AUTO);
   if (!gst_buffer_pool_set_config (pool, config)) {
     gst_object_unref (allocator);
     gst_object_unref (pool);
@@ -403,7 +404,8 @@ gst_va_base_transform_decide_allocation (GstBaseTransform * trans,
     gst_va_dmabuf_allocator_get_format (allocator, &self->priv->srcpad_info,
         NULL);
   } else if (GST_IS_VA_ALLOCATOR (allocator)) {
-    gst_va_allocator_get_format (allocator, &self->priv->srcpad_info, NULL);
+    gst_va_allocator_get_format (allocator, &self->priv->srcpad_info, NULL,
+        NULL);
   }
 
   if (update_allocator)
@@ -759,7 +761,7 @@ _get_sinkpad_pool (GstVaBaseTransform * self)
 
   allocator = gst_va_base_transform_allocator_from_caps (self, caps);
   self->priv->sinkpad_pool = gst_va_pool_new_with_config (caps, size, 1, 0,
-      usage_hint, allocator, &params);
+      usage_hint, GST_VA_FEATURE_AUTO, allocator, &params);
   if (!self->priv->sinkpad_pool) {
     gst_object_unref (allocator);
     return NULL;
@@ -769,7 +771,8 @@ _get_sinkpad_pool (GstVaBaseTransform * self)
     gst_va_dmabuf_allocator_get_format (allocator, &self->priv->sinkpad_info,
         NULL);
   } else if (GST_IS_VA_ALLOCATOR (allocator)) {
-    gst_va_allocator_get_format (allocator, &self->priv->sinkpad_info, NULL);
+    gst_va_allocator_get_format (allocator, &self->priv->sinkpad_info, NULL,
+        NULL);
   }
 
   gst_object_unref (allocator);
index b502f29..f37b8d4 100644 (file)
@@ -323,7 +323,7 @@ _create_reconstruct_pool (GstVaDisplay * display, GArray * surface_formats,
   gst_allocation_params_init (&params);
 
   pool = gst_va_pool_new_with_config (caps, size, 0, max_buffers, usage_hint,
-      allocator, &params);
+      GST_VA_FEATURE_AUTO, allocator, &params);
 
   gst_clear_object (&allocator);
   gst_clear_caps (&caps);
index 69f3882..a40f8a4 100644 (file)
@@ -3165,13 +3165,13 @@ _get_sinkpad_pool (GstVaH264Enc * self)
   allocator = gst_va_allocator_new (self->display, surface_formats);
 
   self->raw_pool = gst_va_pool_new_with_config (caps, size, 1, 0,
-      usage_hint, allocator, &params);
+      usage_hint, GST_VA_FEATURE_AUTO, allocator, &params);
   if (!self->raw_pool) {
     gst_object_unref (allocator);
     return NULL;
   }
 
-  gst_va_allocator_get_format (allocator, &self->sinkpad_info, NULL);
+  gst_va_allocator_get_format (allocator, &self->sinkpad_info, NULL, NULL);
 
   gst_object_unref (allocator);
 
@@ -3709,8 +3709,8 @@ gst_va_h264_enc_propose_allocation (GstVideoEncoder * venc, GstQuery * query)
   if (!(allocator = _allocator_from_caps (self, caps)))
     return FALSE;
 
-  pool = gst_va_pool_new_with_config (caps, size, 1, 0, usage_hint, allocator,
-      &params);
+  pool = gst_va_pool_new_with_config (caps, size, 1, 0, usage_hint,
+      GST_VA_FEATURE_AUTO, allocator, &params);
   if (!pool) {
     gst_object_unref (allocator);
     goto config_failed;