summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVíctor Manuel Jáquez Leal <vjaquez@igalia.com>2020-01-23 16:56:44 +0100
committerVíctor Manuel Jáquez Leal <vjaquez@igalia.com>2020-01-23 21:24:28 +0100
commit21dd66b5e4106fd075e13826eb7999fc4ca81f0c (patch)
tree0de28c1628260cbaaea84861fd67cb0696ac1923
parent78c3afea71568714dbb3c2250337eec5e127ec10 (diff)
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
-rw-r--r--gst-libs/gst/vaapi/gstvaapicontext.c47
-rw-r--r--gst-libs/gst/vaapi/gstvaapicontext.h1
-rw-r--r--gst-libs/gst/vaapi/gstvaapisurface.c62
-rw-r--r--gst-libs/gst/vaapi/gstvaapisurface.h4
4 files changed, 45 insertions, 69 deletions
diff --git a/gst-libs/gst/vaapi/gstvaapicontext.c b/gst-libs/gst/vaapi/gstvaapicontext.c
index 247cb743..315f9324 100644
--- a/gst-libs/gst/vaapi/gstvaapicontext.c
+++ b/gst-libs/gst/vaapi/gstvaapicontext.c
@@ -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;
}
/**
diff --git a/gst-libs/gst/vaapi/gstvaapicontext.h b/gst-libs/gst/vaapi/gstvaapicontext.h
index 26a1dfdc..900fc653 100644
--- a/gst-libs/gst/vaapi/gstvaapicontext.h
+++ b/gst-libs/gst/vaapi/gstvaapicontext.h
@@ -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)
diff --git a/gst-libs/gst/vaapi/gstvaapisurface.c b/gst-libs/gst/vaapi/gstvaapisurface.c
index 5e2e63f6..6a4cb6a0 100644
--- a/gst-libs/gst/vaapi/gstvaapisurface.c
+++ b/gst-libs/gst/vaapi/gstvaapisurface.c
@@ -343,53 +343,6 @@ gst_vaapi_surface_get_display (GstVaapiSurface * 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
* @chroma_type: the surface chroma format
@@ -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;
diff --git a/gst-libs/gst/vaapi/gstvaapisurface.h b/gst-libs/gst/vaapi/gstvaapisurface.h
index 08e5d7de..13de604e 100644
--- a/gst-libs/gst/vaapi/gstvaapisurface.h
+++ b/gst-libs/gst/vaapi/gstvaapisurface.h
@@ -207,10 +207,6 @@ 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);