vaapivideomemory: set direct rendering at run-time

The way to experiment with the direct rendering is through and internal
compiler pre-processor flag.

The current change set enables a way to specified at run-time, as a flag
passed to the allocator at instanciation time.
This commit is contained in:
Víctor Manuel Jáquez Leal 2016-10-20 16:49:22 +02:00
parent 1bc5f00dfe
commit e988298782
3 changed files with 65 additions and 33 deletions

View file

@ -530,7 +530,8 @@ ensure_sinkpad_allocator (GstVaapiPluginBase * plugin, GstVideoInfo * vinfo)
GST_VAAPI_SURFACE_ALLOC_FLAG_LINEAR_STORAGE); GST_VAAPI_SURFACE_ALLOC_FLAG_LINEAR_STORAGE);
} else { } else {
plugin->sinkpad_allocator = plugin->sinkpad_allocator =
gst_vaapi_video_allocator_new (plugin->display, vinfo, 0); gst_vaapi_video_allocator_new (plugin->display, vinfo, 0,
GST_VAAPI_IMAGE_USAGE_FLAG_NATIVE_FORMATS);
} }
return plugin->sinkpad_allocator != NULL; return plugin->sinkpad_allocator != NULL;
} }
@ -542,7 +543,8 @@ ensure_srcpad_allocator (GstVaapiPluginBase * plugin, GstVideoInfo * vinfo)
return TRUE; return TRUE;
plugin->srcpad_allocator = plugin->srcpad_allocator =
gst_vaapi_video_allocator_new (plugin->display, vinfo, 0); gst_vaapi_video_allocator_new (plugin->display, vinfo, 0,
GST_VAAPI_IMAGE_USAGE_FLAG_NATIVE_FORMATS);
return plugin->srcpad_allocator != NULL; return plugin->srcpad_allocator != NULL;
} }

View file

@ -37,9 +37,6 @@ GST_DEBUG_CATEGORY_STATIC (gst_debug_vaapivideomemory);
gst_video_format_to_string (GST_VIDEO_INFO_FORMAT (vip)) gst_video_format_to_string (GST_VIDEO_INFO_FORMAT (vip))
#endif #endif
/* Defined if native VA surface formats are preferred over direct rendering */
#define USE_NATIVE_FORMATS 1
/* ------------------------------------------------------------------------ */ /* ------------------------------------------------------------------------ */
/* --- GstVaapiVideoMemory --- */ /* --- GstVaapiVideoMemory --- */
/* ------------------------------------------------------------------------ */ /* ------------------------------------------------------------------------ */
@ -60,11 +57,23 @@ _init_performance_debug (void)
} }
static inline void static inline void
reset_image_usage (gboolean * flag) reset_image_usage (GstVaapiImageUsageFlags * flag)
{ {
_init_performance_debug (); _init_performance_debug ();
GST_CAT_INFO (CAT_PERFORMANCE, "derive image failed, fallbacking to copy"); GST_CAT_INFO (CAT_PERFORMANCE, "derive image failed, fallbacking to copy");
*flag = FALSE; *flag = GST_VAAPI_IMAGE_USAGE_FLAG_NATIVE_FORMATS;
}
static inline gboolean
use_native_formats (GstVaapiImageUsageFlags flag)
{
return flag == GST_VAAPI_IMAGE_USAGE_FLAG_NATIVE_FORMATS;
}
static inline gboolean
use_direct_rendering (GstVaapiImageUsageFlags flag)
{
return flag == GST_VAAPI_IMAGE_USAGE_FLAG_DIRECT_RENDER;
} }
static guchar * static guchar *
@ -93,14 +102,14 @@ new_image (GstVaapiDisplay * display, const GstVideoInfo * vip)
static gboolean static gboolean
ensure_image (GstVaapiVideoMemory * mem) ensure_image (GstVaapiVideoMemory * mem)
{ {
if (!mem->image && mem->use_direct_rendering) { if (!mem->image && !use_native_formats (mem->usage_flag)) {
mem->image = gst_vaapi_surface_derive_image (mem->surface); mem->image = gst_vaapi_surface_derive_image (mem->surface);
if (!mem->image) { if (!mem->image) {
reset_image_usage (&mem->use_direct_rendering); reset_image_usage (&mem->usage_flag);
} else if (gst_vaapi_surface_get_format (mem->surface) != } else if (gst_vaapi_surface_get_format (mem->surface) !=
GST_VIDEO_INFO_FORMAT (mem->image_info)) { GST_VIDEO_INFO_FORMAT (mem->image_info)) {
gst_vaapi_object_replace (&mem->image, NULL); gst_vaapi_object_replace (&mem->image, NULL);
reset_image_usage (&mem->use_direct_rendering); reset_image_usage (&mem->usage_flag);
} }
} }
@ -119,7 +128,7 @@ ensure_image (GstVaapiVideoMemory * mem)
static gboolean static gboolean
ensure_image_is_current (GstVaapiVideoMemory * mem) ensure_image_is_current (GstVaapiVideoMemory * mem)
{ {
if (mem->use_direct_rendering) if (!use_native_formats (mem->usage_flag))
return TRUE; return TRUE;
if (!GST_VAAPI_VIDEO_MEMORY_FLAG_IS_SET (mem, if (!GST_VAAPI_VIDEO_MEMORY_FLAG_IS_SET (mem,
@ -134,13 +143,14 @@ ensure_image_is_current (GstVaapiVideoMemory * mem)
} }
static GstVaapiSurface * static GstVaapiSurface *
new_surface (GstVaapiDisplay * display, const GstVideoInfo * vip) new_surface (GstVaapiDisplay * display, const GstVideoInfo * vip,
GstVaapiImageUsageFlags usage_flag)
{ {
GstVaapiSurface *surface; GstVaapiSurface *surface;
GstVaapiChromaType chroma_type; GstVaapiChromaType chroma_type;
/* Try with explicit format first */ /* Try with explicit format first */
if (!USE_NATIVE_FORMATS && if (!use_native_formats (usage_flag) &&
GST_VIDEO_INFO_FORMAT (vip) != GST_VIDEO_FORMAT_ENCODED) { GST_VIDEO_INFO_FORMAT (vip) != GST_VIDEO_FORMAT_ENCODED) {
surface = gst_vaapi_surface_new_with_format (display, surface = gst_vaapi_surface_new_with_format (display,
GST_VIDEO_INFO_FORMAT (vip), GST_VIDEO_INFO_WIDTH (vip), GST_VIDEO_INFO_FORMAT (vip), GST_VIDEO_INFO_WIDTH (vip),
@ -190,7 +200,7 @@ ensure_surface (GstVaapiVideoMemory * mem)
static gboolean static gboolean
ensure_surface_is_current (GstVaapiVideoMemory * mem) ensure_surface_is_current (GstVaapiVideoMemory * mem)
{ {
if (mem->use_direct_rendering) if (!use_native_formats (mem->usage_flag))
return TRUE; return TRUE;
if (!GST_VAAPI_VIDEO_MEMORY_FLAG_IS_SET (mem, if (!GST_VAAPI_VIDEO_MEMORY_FLAG_IS_SET (mem,
@ -342,7 +352,7 @@ gst_vaapi_video_memory_new (GstAllocator * base_allocator,
mem->meta = meta ? gst_vaapi_video_meta_ref (meta) : NULL; mem->meta = meta ? gst_vaapi_video_meta_ref (meta) : NULL;
mem->map_type = 0; mem->map_type = 0;
mem->map_count = 0; mem->map_count = 0;
mem->use_direct_rendering = allocator->has_direct_rendering; mem->usage_flag = allocator->usage_flag;
GST_VAAPI_VIDEO_MEMORY_FLAG_SET (mem, GST_VAAPI_VIDEO_MEMORY_FLAG_SET (mem,
GST_VAAPI_VIDEO_MEMORY_FLAG_SURFACE_IS_CURRENT); GST_VAAPI_VIDEO_MEMORY_FLAG_SURFACE_IS_CURRENT);
@ -366,7 +376,7 @@ gst_vaapi_video_memory_reset_image (GstVaapiVideoMemory * mem)
GstVaapiVideoAllocator *const allocator = GstVaapiVideoAllocator *const allocator =
GST_VAAPI_VIDEO_ALLOCATOR_CAST (GST_MEMORY_CAST (mem)->allocator); GST_VAAPI_VIDEO_ALLOCATOR_CAST (GST_MEMORY_CAST (mem)->allocator);
if (mem->use_direct_rendering) if (!use_native_formats (mem->usage_flag))
gst_vaapi_object_replace (&mem->image, NULL); gst_vaapi_object_replace (&mem->image, NULL);
else if (mem->image) { else if (mem->image) {
gst_vaapi_video_pool_put_object (allocator->image_pool, mem->image); gst_vaapi_video_pool_put_object (allocator->image_pool, mem->image);
@ -692,26 +702,27 @@ gst_video_info_update_from_image (GstVideoInfo * vip, GstVaapiImage * image)
static inline void static inline void
allocator_configure_surface_info (GstVaapiDisplay * display, allocator_configure_surface_info (GstVaapiDisplay * display,
GstVaapiVideoAllocator * allocator) GstVaapiVideoAllocator * allocator, GstVaapiImageUsageFlags req_usage_flag)
{ {
const GstVideoInfo *vinfo; const GstVideoInfo *vinfo;
GstVaapiSurface *surface = NULL; GstVaapiSurface *surface = NULL;
GstVaapiImage *image = NULL; GstVaapiImage *image = NULL;
gboolean updated; gboolean updated, has_direct_rendering;
GstVideoFormat fmt; GstVideoFormat fmt;
vinfo = &allocator->video_info; vinfo = &allocator->video_info;
allocator->usage_flag = GST_VAAPI_IMAGE_USAGE_FLAG_NATIVE_FORMATS;
fmt = gst_vaapi_video_format_get_best_native (GST_VIDEO_INFO_FORMAT (vinfo)); fmt = gst_vaapi_video_format_get_best_native (GST_VIDEO_INFO_FORMAT (vinfo));
gst_video_info_set_format (&allocator->surface_info, fmt, gst_video_info_set_format (&allocator->surface_info, fmt,
GST_VIDEO_INFO_WIDTH (vinfo), GST_VIDEO_INFO_HEIGHT (vinfo)); GST_VIDEO_INFO_WIDTH (vinfo), GST_VIDEO_INFO_HEIGHT (vinfo));
/* nothing to configure */ /* nothing to configure */
if (USE_NATIVE_FORMATS || if (use_native_formats (req_usage_flag)
GST_VIDEO_INFO_FORMAT (vinfo) == GST_VIDEO_FORMAT_ENCODED) || GST_VIDEO_INFO_FORMAT (vinfo) == GST_VIDEO_FORMAT_ENCODED)
return; return;
surface = new_surface (display, vinfo); surface = new_surface (display, vinfo, req_usage_flag);
if (!surface) if (!surface)
goto error_no_surface; goto error_no_surface;
image = gst_vaapi_surface_derive_image (surface); image = gst_vaapi_surface_derive_image (surface);
@ -722,15 +733,18 @@ allocator_configure_surface_info (GstVaapiDisplay * display,
updated = gst_video_info_update_from_image (&allocator->surface_info, image); updated = gst_video_info_update_from_image (&allocator->surface_info, image);
allocator->has_direct_rendering = !USE_NATIVE_FORMATS && updated && has_direct_rendering = updated && use_direct_rendering (req_usage_flag)
(GST_VAAPI_IMAGE_FORMAT (image) == GST_VIDEO_INFO_FORMAT (vinfo)); && (GST_VAAPI_IMAGE_FORMAT (image) == GST_VIDEO_INFO_FORMAT (vinfo));
GST_INFO ("has direct-rendering for %s surfaces: %s",
GST_VIDEO_INFO_FORMAT_STRING (&allocator->surface_info),
allocator->has_direct_rendering ? "yes" : "no");
gst_vaapi_image_unmap (image); gst_vaapi_image_unmap (image);
GST_INFO_OBJECT (allocator, "has %sdirect-rendering for %s surfaces",
has_direct_rendering ? "" : "no ",
GST_VIDEO_INFO_FORMAT_STRING (&allocator->surface_info));
if (has_direct_rendering)
allocator->usage_flag = GST_VAAPI_IMAGE_USAGE_FLAG_DIRECT_RENDER;
bail: bail:
if (image) if (image)
gst_vaapi_object_unref (image); gst_vaapi_object_unref (image);
@ -763,7 +777,7 @@ allocator_configure_image_info (GstVaapiDisplay * display,
GstVaapiImage *image = NULL; GstVaapiImage *image = NULL;
const GstVideoInfo *vinfo; const GstVideoInfo *vinfo;
if (allocator->has_direct_rendering) { if (!use_native_formats (allocator->usage_flag)) {
allocator->image_info = allocator->surface_info; allocator->image_info = allocator->surface_info;
return; return;
} }
@ -788,7 +802,8 @@ bail:
GstAllocator * GstAllocator *
gst_vaapi_video_allocator_new (GstVaapiDisplay * display, gst_vaapi_video_allocator_new (GstVaapiDisplay * display,
const GstVideoInfo * vip, guint surface_alloc_flags) const GstVideoInfo * vip, guint surface_alloc_flags,
GstVaapiImageUsageFlags req_usage_flag)
{ {
GstVaapiVideoAllocator *allocator; GstVaapiVideoAllocator *allocator;
@ -801,7 +816,7 @@ gst_vaapi_video_allocator_new (GstVaapiDisplay * display,
allocator->video_info = *vip; allocator->video_info = *vip;
allocator_configure_surface_info (display, allocator); allocator_configure_surface_info (display, allocator, req_usage_flag);
allocator->surface_pool = gst_vaapi_surface_pool_new_full (display, allocator->surface_pool = gst_vaapi_surface_pool_new_full (display,
&allocator->surface_info, surface_alloc_flags); &allocator->surface_info, surface_alloc_flags);
if (!allocator->surface_pool) if (!allocator->surface_pool)

View file

@ -90,6 +90,20 @@ typedef enum
GST_VAAPI_VIDEO_MEMORY_FLAG_IMAGE_IS_CURRENT = GST_MEMORY_FLAG_LAST << 1, GST_VAAPI_VIDEO_MEMORY_FLAG_IMAGE_IS_CURRENT = GST_MEMORY_FLAG_LAST << 1,
} GstVaapiVideoMemoryFlags; } GstVaapiVideoMemoryFlags;
/**
* GstVaapiImageUsageFlags:
* @GST_VAAPI_IMAGE_USAGE_FLAG_NATIVE_FORMATS: will use vaCreateImage +
* va{Put,Get}Image when writing or reading onto the system memory.
* @GST_VAAPI_IMAGE_USAGE_FLAG_DIRECT_RENDER: will try to use
* vaDeriveImage with reading data onto the system memory.
*
* Set the usage of GstVaapiImage in GstVaapiVideoMemory.
**/
typedef enum {
GST_VAAPI_IMAGE_USAGE_FLAG_NATIVE_FORMATS,
GST_VAAPI_IMAGE_USAGE_FLAG_DIRECT_RENDER,
} GstVaapiImageUsageFlags;
/** /**
* GstVaapiVideoMemory: * GstVaapiVideoMemory:
* *
@ -109,7 +123,7 @@ struct _GstVaapiVideoMemory
GstVaapiVideoMeta *meta; GstVaapiVideoMeta *meta;
guint map_type; guint map_type;
gint map_count; gint map_count;
gboolean use_direct_rendering; GstVaapiImageUsageFlags usage_flag;
}; };
G_GNUC_INTERNAL G_GNUC_INTERNAL
@ -166,7 +180,7 @@ struct _GstVaapiVideoAllocator
GstVaapiVideoPool *surface_pool; GstVaapiVideoPool *surface_pool;
GstVideoInfo image_info; GstVideoInfo image_info;
GstVaapiVideoPool *image_pool; GstVaapiVideoPool *image_pool;
gboolean has_direct_rendering; GstVaapiImageUsageFlags usage_flag;
}; };
/** /**
@ -186,7 +200,8 @@ gst_vaapi_video_allocator_get_type (void) G_GNUC_CONST;
G_GNUC_INTERNAL G_GNUC_INTERNAL
GstAllocator * GstAllocator *
gst_vaapi_video_allocator_new (GstVaapiDisplay * display, gst_vaapi_video_allocator_new (GstVaapiDisplay * display,
const GstVideoInfo * vip, guint surface_alloc_flags); const GstVideoInfo * vip, guint surface_alloc_flags,
GstVaapiImageUsageFlags req_usage_flag);
/* ------------------------------------------------------------------------ */ /* ------------------------------------------------------------------------ */
/* --- GstVaapiDmaBufMemory --- */ /* --- GstVaapiDmaBufMemory --- */