mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-18 14:26:43 +00:00
libs: context: select vaCreateSurfaces version according attributes
This commit tries to centralize the selection of vaCreateSurfaces version, instead of having fallbacks everywhere. These fallbacks are hacks, added because new drivers use the latest version of vaCreateSurfaces (with surface attributes) [1], meanwhile old drivers (or profiles as JPEG decoder in i965) might rather use the old version. In order to select which method, there's detected hack: each config context has a list of valid formats, in the case of JPEG decoder the list only contains "rare" 4:2:2 formats (ICM3, GRAY8) which aren't handled correctly by the current gstreamer-vaapi code [2]. The hack consist in identify if the format list contains an arbitrary preferred format (which is suposedly well supported by gstreamer-vaapi, mostly NV12). If no prefered colour format is found, the the old version of vaCreateSurfaces is used, and the surfaces wil be mapped into a image with their own color format. 1. https://bugzilla.gnome.org/show_bug.cgi?id=797143 2. https://bugzilla.gnome.org/show_bug.cgi?id=797222
This commit is contained in:
parent
78c3afea71
commit
21dd66b5e4
4 changed files with 45 additions and 69 deletions
|
@ -73,6 +73,33 @@ ensure_attributes (GstVaapiContext * context)
|
|||
return (context->attribs != NULL);
|
||||
}
|
||||
|
||||
/* looks for the (very arbritrary) preferred format from the requested
|
||||
* context chroma type, in the context attributes */
|
||||
static GstVideoFormat
|
||||
get_preferred_format (GstVaapiContext * context)
|
||||
{
|
||||
const GstVaapiContextInfo *const cip = &context->info;
|
||||
GArray *formats;
|
||||
guint i;
|
||||
|
||||
if (context->preferred_format != GST_VIDEO_FORMAT_UNKNOWN)
|
||||
return context->preferred_format;
|
||||
|
||||
if (!ensure_attributes (context) || !context->attribs->formats)
|
||||
return GST_VIDEO_FORMAT_UNKNOWN;
|
||||
|
||||
formats = context->attribs->formats;
|
||||
for (i = 0; i < formats->len; i++) {
|
||||
GstVideoFormat format = g_array_index (formats, GstVideoFormat, i);
|
||||
if (format == gst_vaapi_video_format_from_chroma (cip->chroma_type)) {
|
||||
context->preferred_format = format;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return context->preferred_format;
|
||||
}
|
||||
|
||||
static inline gboolean
|
||||
context_get_attribute (GstVaapiContext * context, VAConfigAttribType type,
|
||||
guint * out_value_ptr)
|
||||
|
@ -88,6 +115,9 @@ context_destroy_surfaces (GstVaapiContext * context)
|
|||
g_ptr_array_unref (context->surfaces);
|
||||
context->surfaces = NULL;
|
||||
}
|
||||
|
||||
context->preferred_format = GST_VIDEO_FORMAT_UNKNOWN;
|
||||
|
||||
gst_vaapi_video_pool_replace (&context->surfaces_pool, NULL);
|
||||
}
|
||||
|
||||
|
@ -130,18 +160,22 @@ context_destroy (GstVaapiContext * context)
|
|||
static gboolean
|
||||
context_ensure_surfaces (GstVaapiContext * context)
|
||||
{
|
||||
GstVaapiDisplay *display = GST_VAAPI_CONTEXT_DISPLAY (context);
|
||||
const GstVaapiContextInfo *const cip = &context->info;
|
||||
const guint num_surfaces = cip->ref_frames + SCRATCH_SURFACES_COUNT;
|
||||
GstVaapiSurface *surface;
|
||||
GstVideoFormat format;
|
||||
guint i;
|
||||
|
||||
if (!ensure_attributes (context))
|
||||
return FALSE;
|
||||
|
||||
format = get_preferred_format (context);
|
||||
for (i = context->surfaces->len; i < num_surfaces; i++) {
|
||||
surface =
|
||||
gst_vaapi_surface_new_from_formats (GST_VAAPI_CONTEXT_DISPLAY (context),
|
||||
cip->chroma_type, cip->width, cip->height, context->attribs->formats);
|
||||
if (format != GST_VIDEO_FORMAT_UNKNOWN) {
|
||||
surface = gst_vaapi_surface_new_with_format (display, format, cip->width,
|
||||
cip->height);
|
||||
} else {
|
||||
surface = gst_vaapi_surface_new (display, cip->chroma_type, cip->width,
|
||||
cip->height);
|
||||
}
|
||||
if (!surface)
|
||||
return FALSE;
|
||||
g_ptr_array_add (context->surfaces, surface);
|
||||
|
@ -397,6 +431,7 @@ gst_vaapi_context_init (GstVaapiContext * context,
|
|||
context->reset_on_resize = TRUE;
|
||||
|
||||
context->attribs = NULL;
|
||||
context->preferred_format = GST_VIDEO_FORMAT_UNKNOWN;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -115,6 +115,7 @@ struct _GstVaapiContext
|
|||
GstVaapiVideoPool *surfaces_pool;
|
||||
gboolean reset_on_resize;
|
||||
GstVaapiConfigSurfaceAttributes *attribs;
|
||||
GstVideoFormat preferred_format;
|
||||
};
|
||||
|
||||
#define GST_VAAPI_CONTEXT_ID(context) (((GstVaapiContext *)(context))->object_id)
|
||||
|
|
|
@ -342,53 +342,6 @@ gst_vaapi_surface_get_display (GstVaapiSurface * surface)
|
|||
return GST_VAAPI_SURFACE_DISPLAY (surface);
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_vaapi_surface_new_from_formats:
|
||||
* @display: a #GstVaapiDisplay
|
||||
* @chroma_type: the surface chroma format
|
||||
* @width: the requested surface width
|
||||
* @height: the requested surface height
|
||||
* @formats: the limited format list
|
||||
*
|
||||
* Creates a new #GstVaapiSurface with a @chroma_type valid for any
|
||||
* format in @formats; If there aren't any, the returned surface is
|
||||
* created forcing the passed @chroma_type.
|
||||
*
|
||||
* Return value: the newly allocated #GstVaapiSurface object
|
||||
*/
|
||||
GstVaapiSurface *
|
||||
gst_vaapi_surface_new_from_formats (GstVaapiDisplay * display,
|
||||
GstVaapiChromaType chroma_type, guint width, guint height, GArray * formats)
|
||||
{
|
||||
GstVaapiSurface *surface;
|
||||
guint i;
|
||||
|
||||
if (formats) {
|
||||
for (i = 0; i < formats->len; i++) {
|
||||
GstVideoFormat format = g_array_index (formats, GstVideoFormat, i);
|
||||
if (format == gst_vaapi_video_format_from_chroma (chroma_type))
|
||||
return gst_vaapi_surface_new (display, chroma_type, width, height);
|
||||
}
|
||||
}
|
||||
|
||||
/* Fallback: if there's no format valid for the chroma type let's
|
||||
* just use the passed chroma */
|
||||
surface = gst_vaapi_surface_create (display);
|
||||
if (!surface)
|
||||
return NULL;
|
||||
if (!gst_vaapi_surface_init (surface, chroma_type, width, height))
|
||||
goto error;
|
||||
|
||||
return surface;
|
||||
|
||||
/* ERRORS */
|
||||
error:
|
||||
{
|
||||
gst_vaapi_surface_unref (surface);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_vaapi_surface_new:
|
||||
* @display: a #GstVaapiDisplay
|
||||
|
@ -399,6 +352,9 @@ error:
|
|||
* Creates a new #GstVaapiSurface with the specified chroma format and
|
||||
* dimensions.
|
||||
*
|
||||
* NOTE: this method for creating surfaces uses deprecated VA API,
|
||||
* which is still used by drivers (v.gr. i965 for jpeg decoding).
|
||||
*
|
||||
* Return value: the newly allocated #GstVaapiSurface object
|
||||
*/
|
||||
GstVaapiSurface *
|
||||
|
@ -413,18 +369,6 @@ gst_vaapi_surface_new (GstVaapiDisplay * display,
|
|||
if (!surface)
|
||||
return NULL;
|
||||
|
||||
/* first try a recent version of vaCreateSurface, and later use as
|
||||
* fallback its old version */
|
||||
{
|
||||
GstVideoInfo vi;
|
||||
GstVideoFormat surface_format;
|
||||
|
||||
surface_format = gst_vaapi_video_format_from_chroma (chroma_type);
|
||||
gst_video_info_set_format (&vi, surface_format, width, height);
|
||||
|
||||
if (gst_vaapi_surface_init_full (surface, &vi, 0))
|
||||
return surface;
|
||||
}
|
||||
if (!gst_vaapi_surface_init (surface, chroma_type, width, height))
|
||||
goto error;
|
||||
return surface;
|
||||
|
|
|
@ -206,10 +206,6 @@ gst_vaapi_surface_unref (GstVaapiSurface * surface)
|
|||
GstVaapiDisplay *
|
||||
gst_vaapi_surface_get_display (GstVaapiSurface * surface);
|
||||
|
||||
GstVaapiSurface *
|
||||
gst_vaapi_surface_new_from_formats (GstVaapiDisplay * display,
|
||||
GstVaapiChromaType chroma_type, guint width, guint height, GArray * formts);
|
||||
|
||||
GstVaapiSurface *
|
||||
gst_vaapi_surface_new (GstVaapiDisplay * display,
|
||||
GstVaapiChromaType chroma_type, guint width, guint height);
|
||||
|
|
Loading…
Reference in a new issue