libs: va: add VA allocator parameter for derived images usage.

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>
This commit is contained in:
Víctor Manuel Jáquez Leal 2022-03-29 14:52:33 +02:00
parent a801d6dd63
commit 6d2f57b6c7
10 changed files with 109 additions and 54 deletions

View file

@ -25,7 +25,15 @@
#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>

View 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;
}

View 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);

View 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);

View 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);

View 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,

View 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;

View 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);

View 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);

View 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;