2 * gstvaapipluginutil.h - VA-API plugin helpers
4 * Copyright (C) 2011-2014 Intel Corporation
5 * Author: Gwenole Beauchesne <gwenole.beauchesne@intel.com>
6 * Copyright (C) 2011 Collabora
7 * Author: Nicolas Dufresne <nicolas.dufresne@collabora.co.uk>
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public License
11 * as published by the Free Software Foundation; either version 2.1
12 * of the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free
21 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
22 * Boston, MA 02110-1301 USA
25 #include "gstcompat.h"
26 #include "gstvaapivideocontext.h"
28 # include <gst/vaapi/gstvaapidisplay_drm.h>
31 # include <gst/vaapi/gstvaapidisplay_x11.h>
34 # include <gst/vaapi/gstvaapidisplay_glx.h>
37 # include <gst/vaapi/gstvaapidisplay_egl.h>
40 # include <gst/vaapi/gstvaapidisplay_wayland.h>
42 #include "gstvaapipluginutil.h"
43 #include "gstvaapipluginbase.h"
45 /* Environment variable for disable driver white-list */
46 #define GST_VAAPI_ALL_DRIVERS_ENV "GST_VAAPI_ALL_DRIVERS"
48 typedef GstVaapiDisplay *(*GstVaapiDisplayCreateFunc) (const gchar *);
49 typedef GstVaapiDisplay *(*GstVaapiDisplayCreateFromHandleFunc) (gpointer);
53 const gchar *type_str;
54 GstVaapiDisplayType type;
55 GstVaapiDisplayCreateFunc create_display;
56 GstVaapiDisplayCreateFromHandleFunc create_display_from_handle;
60 static const DisplayMap g_display_map[] = {
63 GST_VAAPI_DISPLAY_TYPE_WAYLAND,
64 gst_vaapi_display_wayland_new,
65 (GstVaapiDisplayCreateFromHandleFunc)
66 gst_vaapi_display_wayland_new_with_display},
70 GST_VAAPI_DISPLAY_TYPE_GLX,
71 gst_vaapi_display_glx_new,
72 (GstVaapiDisplayCreateFromHandleFunc)
73 gst_vaapi_display_glx_new_with_display},
77 GST_VAAPI_DISPLAY_TYPE_X11,
78 gst_vaapi_display_x11_new,
79 (GstVaapiDisplayCreateFromHandleFunc)
80 gst_vaapi_display_x11_new_with_display},
84 GST_VAAPI_DISPLAY_TYPE_DRM,
85 gst_vaapi_display_drm_new},
91 static GstVaapiDisplay *
92 gst_vaapi_create_display (GstVaapiDisplayType display_type,
93 const gchar * display_name)
95 GstVaapiDisplay *display = NULL;
98 for (m = g_display_map; m->type_str != NULL; m++) {
99 if (display_type != GST_VAAPI_DISPLAY_TYPE_ANY && display_type != m->type)
102 display = m->create_display (display_name);
103 if (display || display_type != GST_VAAPI_DISPLAY_TYPE_ANY)
109 #if USE_GST_GL_HELPERS
110 static GstVaapiDisplay *
111 gst_vaapi_create_display_from_handle (GstVaapiDisplayType display_type,
114 GstVaapiDisplay *display;
117 if (display_type == GST_VAAPI_DISPLAY_TYPE_ANY)
120 for (m = g_display_map; m->type_str != NULL; m++) {
121 if (m->type == display_type) {
122 display = m->create_display_from_handle ?
123 m->create_display_from_handle (handle) : NULL;
131 static GstVaapiDisplay *
132 gst_vaapi_create_display_from_gl_context (GstObject * gl_context_object)
134 #if USE_GST_GL_HELPERS
135 GstGLContext *const gl_context = GST_GL_CONTEXT (gl_context_object);
136 GstGLDisplay *const gl_display = gst_gl_context_get_display (gl_context);
137 gpointer native_display =
138 GSIZE_TO_POINTER (gst_gl_display_get_handle (gl_display));
139 GstGLPlatform platform = gst_gl_context_get_gl_platform (gl_context);
140 GstVaapiDisplay *display, *out_display;
141 GstVaapiDisplayType display_type;
143 switch (gst_gl_display_get_handle_type (gl_display)) {
145 case GST_GL_DISPLAY_TYPE_X11:
147 if (platform == GST_GL_PLATFORM_GLX) {
148 display_type = GST_VAAPI_DISPLAY_TYPE_GLX;
152 display_type = GST_VAAPI_DISPLAY_TYPE_X11;
156 case GST_GL_DISPLAY_TYPE_WAYLAND:
157 display_type = GST_VAAPI_DISPLAY_TYPE_WAYLAND;
160 case GST_GL_DISPLAY_TYPE_ANY:{
161 /* Derive from the active window */
162 GstGLWindow *const gl_window = gst_gl_context_get_window (gl_context);
163 const gchar *const gl_window_type = g_getenv ("GST_GL_WINDOW");
165 display_type = GST_VAAPI_DISPLAY_TYPE_ANY;
168 native_display = GSIZE_TO_POINTER (gst_gl_window_get_display (gl_window));
170 if (gl_window_type) {
172 if (!display_type && g_strcmp0 (gl_window_type, "x11") == 0)
173 display_type = GST_VAAPI_DISPLAY_TYPE_X11;
176 if (!display_type && g_strcmp0 (gl_window_type, "wayland") == 0)
177 display_type = GST_VAAPI_DISPLAY_TYPE_WAYLAND;
180 #if USE_X11 && GST_GL_HAVE_WINDOW_X11
182 display_type = GST_VAAPI_DISPLAY_TYPE_X11;
183 #elif USE_WAYLAND && GST_GL_HAVE_WINDOW_WAYLAND
185 display_type = GST_VAAPI_DISPLAY_TYPE_WAYLAND;
188 gst_object_unref (gl_window);
192 display_type = GST_VAAPI_DISPLAY_TYPE_ANY;
195 gst_object_unref (gl_display);
197 display = gst_vaapi_create_display_from_handle (display_type, native_display);
203 case GST_GL_PLATFORM_EGL:{
206 switch (gst_gl_context_get_gl_api (gl_context)) {
207 case GST_GL_API_GLES1:
209 goto create_egl_display;
210 case GST_GL_API_GLES2:
212 goto create_egl_display;
213 case GST_GL_API_OPENGL:
214 case GST_GL_API_OPENGL3:
217 out_display = gst_vaapi_display_egl_new (display, gles_version);
224 gst_vaapi_display_unref (display);
227 gst_vaapi_display_egl_set_gl_context (GST_VAAPI_DISPLAY_EGL (out_display),
228 GSIZE_TO_POINTER (gst_gl_context_get_gl_context (gl_context)));
233 out_display = gst_vaapi_display_ref (display);
236 gst_vaapi_display_unref (display);
239 GST_ERROR ("unsupported GStreamer version %s", GST_API_VERSION_S);
244 gst_vaapi_find_gl_context (GstElement * element)
246 GstObject *gl_context;
247 GstVaapiPluginBase *const plugin = GST_VAAPI_PLUGIN_BASE (element);
249 /* if the element is vaapisink or any vaapi encoder it doesn't need
250 * to know a GstGLContext in order to create an appropriate
251 * GstVaapiDisplay. Let's them to choose their own
253 if (GST_IS_VIDEO_SINK (element) || GST_IS_VIDEO_ENCODER (element))
257 if (!gst_vaapi_find_gl_local_context (element, &gl_context))
258 gl_context = gst_vaapi_plugin_base_create_gl_context (plugin);
261 gst_vaapi_plugin_base_set_gl_context (plugin, gl_context);
262 gst_object_unref (gl_context);
267 gst_vaapi_ensure_display (GstElement * element, GstVaapiDisplayType type)
269 GstVaapiPluginBase *const plugin = GST_VAAPI_PLUGIN_BASE (element);
270 GstVaapiDisplay *display = NULL;
272 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
274 if (gst_vaapi_video_context_prepare (element, &plugin->display)) {
275 /* Neighbour found and it updated the display */
276 if (gst_vaapi_plugin_base_has_display_type (plugin, type))
280 /* Query for a local GstGL context. If it's found, it will be used
281 * to create the VA display */
282 if (!plugin->gl_context)
283 gst_vaapi_find_gl_context (element);
285 /* If no neighboor, or application not interested, use system default */
286 if (plugin->gl_context) {
287 display = gst_vaapi_create_display_from_gl_context (plugin->gl_context);
288 /* Cannot instantiate VA display based on GL context. Reset the
289 * requested display type to ANY to try again */
291 gst_vaapi_plugin_base_set_display_type (plugin,
292 GST_VAAPI_DISPLAY_TYPE_ANY);
295 display = gst_vaapi_create_display (type, plugin->display_name);
299 gst_vaapi_video_context_propagate (element, display);
300 gst_vaapi_display_unref (display);
305 gst_vaapi_handle_context_query (GstElement * element, GstQuery * query)
307 GstVaapiPluginBase *const plugin = GST_VAAPI_PLUGIN_BASE (element);
308 const gchar *type = NULL;
309 GstContext *context, *old_context;
311 g_return_val_if_fail (query != NULL, FALSE);
313 #if USE_GST_GL_HELPERS
314 if (plugin->gl_display && plugin->gl_context && plugin->gl_other_context) {
315 if (gst_gl_handle_context_query (element, query,
316 (GstGLDisplay *) plugin->gl_display,
317 (GstGLContext *) plugin->gl_context,
318 (GstGLContext *) plugin->gl_other_context))
323 if (!plugin->display)
326 if (!gst_query_parse_context_type (query, &type))
329 if (g_strcmp0 (type, GST_VAAPI_DISPLAY_CONTEXT_TYPE_NAME))
332 gst_query_parse_context (query, &old_context);
334 context = gst_context_copy (old_context);
335 gst_vaapi_video_context_set_display (context, plugin->display);
337 context = gst_vaapi_video_context_new_with_display (plugin->display, FALSE);
340 gst_query_set_context (query, context);
341 gst_context_unref (context);
347 gst_vaapi_append_surface_caps (GstCaps * out_caps, GstCaps * in_caps)
349 GstStructure *structure;
350 const GValue *v_width, *v_height, *v_framerate, *v_par;
351 guint i, n_structures;
353 structure = gst_caps_get_structure (in_caps, 0);
354 v_width = gst_structure_get_value (structure, "width");
355 v_height = gst_structure_get_value (structure, "height");
356 v_framerate = gst_structure_get_value (structure, "framerate");
357 v_par = gst_structure_get_value (structure, "pixel-aspect-ratio");
358 if (!v_width || !v_height)
361 n_structures = gst_caps_get_size (out_caps);
362 for (i = 0; i < n_structures; i++) {
363 structure = gst_caps_get_structure (out_caps, i);
364 gst_structure_set_value (structure, "width", v_width);
365 gst_structure_set_value (structure, "height", v_height);
367 gst_structure_set_value (structure, "framerate", v_framerate);
369 gst_structure_set_value (structure, "pixel-aspect-ratio", v_par);
375 gst_vaapi_apply_composition (GstVaapiSurface * surface, GstBuffer * buffer)
377 GstVideoOverlayCompositionMeta *const cmeta =
378 gst_buffer_get_video_overlay_composition_meta (buffer);
379 GstVideoOverlayComposition *composition = NULL;
382 composition = cmeta->overlay;
383 return gst_vaapi_surface_set_subpictures_from_composition (surface,
388 gst_vaapi_value_set_format (GValue * value, GstVideoFormat format)
392 str = gst_video_format_to_string (format);
396 g_value_init (value, G_TYPE_STRING);
397 g_value_set_string (value, str);
402 gst_vaapi_value_set_format_list (GValue * value, GArray * formats)
404 GValue v_format = G_VALUE_INIT;
407 g_value_init (value, GST_TYPE_LIST);
408 for (i = 0; i < formats->len; i++) {
409 GstVideoFormat const format = g_array_index (formats, GstVideoFormat, i);
411 if (!gst_vaapi_value_set_format (&v_format, format))
413 gst_value_list_append_value (value, &v_format);
414 g_value_unset (&v_format);
420 set_video_template_caps (GstCaps * caps)
422 GstStructure *const structure = gst_caps_get_structure (caps, 0);
424 gst_structure_set (structure,
425 "width", GST_TYPE_INT_RANGE, 1, G_MAXINT,
426 "height", GST_TYPE_INT_RANGE, 1, G_MAXINT,
427 "framerate", GST_TYPE_FRACTION_RANGE, 0, 1, G_MAXINT, 1, NULL);
431 gst_vaapi_video_format_new_template_caps (GstVideoFormat format)
435 g_return_val_if_fail (format != GST_VIDEO_FORMAT_UNKNOWN, NULL);
437 caps = gst_caps_new_empty_simple ("video/x-raw");
441 gst_caps_set_simple (caps,
442 "format", G_TYPE_STRING, gst_video_format_to_string (format), NULL);
443 set_video_template_caps (caps);
448 gst_vaapi_video_format_new_template_caps_from_list (GArray * formats)
450 GValue v_formats = G_VALUE_INIT;
453 caps = gst_caps_new_empty_simple ("video/x-raw");
457 if (!gst_vaapi_value_set_format_list (&v_formats, formats)) {
458 gst_caps_unref (caps);
462 gst_caps_set_value (caps, "format", &v_formats);
463 set_video_template_caps (caps);
464 g_value_unset (&v_formats);
469 gst_vaapi_video_format_new_template_caps_with_features (GstVideoFormat format,
470 const gchar * features_string)
472 GstCapsFeatures *features;
475 caps = gst_vaapi_video_format_new_template_caps (format);
479 features = gst_caps_features_new (features_string, NULL);
481 gst_caps_unref (caps);
484 gst_caps_set_features (caps, 0, features);
488 static GstVideoFormat
489 gst_vaapi_find_preferred_format (const GValue * format_list,
490 GstVideoFormat native_format)
493 GstVideoFormat out_format;
496 /* if one format, that is the one */
497 if (G_VALUE_HOLDS_STRING (format_list))
498 return gst_video_format_from_string (g_value_get_string (format_list));
500 if (!GST_VALUE_HOLDS_LIST (format_list)) {
501 GST_ERROR ("negotiated caps do not have a valid format");
502 return GST_VIDEO_FORMAT_UNKNOWN;
505 if (native_format == GST_VIDEO_FORMAT_UNKNOWN
506 || native_format == GST_VIDEO_FORMAT_ENCODED) {
507 native_format = GST_VIDEO_FORMAT_NV12; /* default VA format */
510 /* search our native format in the list */
511 for (i = 0; i < gst_value_list_get_size (format_list); i++) {
512 frmt = gst_value_list_get_value (format_list, i);
513 out_format = gst_video_format_from_string (g_value_get_string (frmt));
515 /* GStreamer do not handle encoded formats nicely. Try the next
517 if (out_format == GST_VIDEO_FORMAT_ENCODED)
520 if (native_format == out_format)
524 /* just pick the first valid format in the list */
527 frmt = gst_value_list_get_value (format_list, i++);
528 out_format = gst_video_format_from_string (g_value_get_string (frmt));
529 } while (out_format == GST_VIDEO_FORMAT_ENCODED);
535 gst_vaapi_find_preferred_caps_feature (GstPad * pad, GstCaps * allowed_caps,
536 GstVideoFormat * out_format_ptr)
538 GstVaapiCapsFeature feature = GST_VAAPI_CAPS_FEATURE_NOT_NEGOTIATED;
539 guint i, j, num_structures;
540 GstCaps *out_caps, *caps = NULL;
541 static const guint feature_list[] = { GST_VAAPI_CAPS_FEATURE_VAAPI_SURFACE,
542 GST_VAAPI_CAPS_FEATURE_DMABUF,
543 GST_VAAPI_CAPS_FEATURE_GL_TEXTURE_UPLOAD_META,
544 GST_VAAPI_CAPS_FEATURE_SYSTEM_MEMORY,
547 out_caps = gst_pad_peer_query_caps (pad, allowed_caps);
551 if (gst_caps_is_any (out_caps) || gst_caps_is_empty (out_caps))
554 feature = GST_VAAPI_CAPS_FEATURE_SYSTEM_MEMORY;
555 num_structures = gst_caps_get_size (out_caps);
556 for (i = 0; i < num_structures; i++) {
557 GstCapsFeatures *const features = gst_caps_get_features (out_caps, i);
558 GstStructure *const structure = gst_caps_get_structure (out_caps, i);
560 /* Skip ANY features, we need an exact match for correct evaluation */
561 if (gst_caps_features_is_any (features))
564 gst_caps_replace (&caps, NULL);
565 caps = gst_caps_new_full (gst_structure_copy (structure), NULL);
568 gst_caps_set_features (caps, 0, gst_caps_features_copy (features));
570 for (j = 0; j < G_N_ELEMENTS (feature_list); j++) {
571 if (gst_vaapi_caps_feature_contains (caps, feature_list[j])
572 && feature < feature_list[j]) {
573 feature = feature_list[j];
578 /* Stop at the first match, the caps should already be sorted out
579 by preference order from downstream elements */
580 if (feature != GST_VAAPI_CAPS_FEATURE_SYSTEM_MEMORY)
587 if (out_format_ptr) {
588 GstVideoFormat out_format;
589 GstStructure *structure;
590 const GValue *format_list;
592 /* if the best feature is SystemMemory, we should use the first
593 * caps in the peer caps set, which is the preferred by
595 if (feature == GST_VAAPI_CAPS_FEATURE_SYSTEM_MEMORY)
596 gst_caps_replace (&caps, out_caps);
598 /* use the first caps, which is the preferred by downstream. */
599 structure = gst_caps_get_structure (caps, 0);
602 format_list = gst_structure_get_value (structure, "format");
605 out_format = gst_vaapi_find_preferred_format (format_list, *out_format_ptr);
606 if (out_format == GST_VIDEO_FORMAT_UNKNOWN)
609 *out_format_ptr = out_format;
613 gst_caps_replace (&caps, NULL);
614 gst_caps_replace (&out_caps, NULL);
619 gst_vaapi_caps_feature_to_string (GstVaapiCapsFeature feature)
624 case GST_VAAPI_CAPS_FEATURE_SYSTEM_MEMORY:
625 str = GST_CAPS_FEATURE_MEMORY_SYSTEM_MEMORY;
627 case GST_VAAPI_CAPS_FEATURE_GL_TEXTURE_UPLOAD_META:
628 str = GST_CAPS_FEATURE_META_GST_VIDEO_GL_TEXTURE_UPLOAD_META;
630 case GST_VAAPI_CAPS_FEATURE_DMABUF:
631 str = GST_CAPS_FEATURE_MEMORY_DMABUF;
633 case GST_VAAPI_CAPS_FEATURE_VAAPI_SURFACE:
634 str = GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE;
644 gst_caps_set_interlaced (GstCaps * caps, GstVideoInfo * vip)
646 GstVideoInterlaceMode mode;
647 const gchar *mode_str;
649 mode = vip ? GST_VIDEO_INFO_INTERLACE_MODE (vip) :
650 GST_VIDEO_INTERLACE_MODE_PROGRESSIVE;
652 case GST_VIDEO_INTERLACE_MODE_PROGRESSIVE:
653 mode_str = "progressive";
655 case GST_VIDEO_INTERLACE_MODE_INTERLEAVED:
656 mode_str = "interleaved";
658 case GST_VIDEO_INTERLACE_MODE_MIXED:
662 GST_ERROR ("unsupported `interlace-mode' %d", mode);
666 gst_caps_set_simple (caps, "interlace-mode", G_TYPE_STRING, mode_str, NULL);
671 _gst_caps_has_feature (const GstCaps * caps, const gchar * feature)
675 for (i = 0; i < gst_caps_get_size (caps); i++) {
676 GstCapsFeatures *const features = gst_caps_get_features (caps, i);
677 /* Skip ANY features, we need an exact match for correct evaluation */
678 if (gst_caps_features_is_any (features))
680 if (gst_caps_features_contains (features, feature))
688 gst_vaapi_caps_feature_contains (const GstCaps * caps,
689 GstVaapiCapsFeature feature)
691 const gchar *feature_str;
693 g_return_val_if_fail (caps != NULL, FALSE);
695 feature_str = gst_vaapi_caps_feature_to_string (feature);
699 return _gst_caps_has_feature (caps, feature_str);
702 /* Checks whether the supplied caps contain VA surfaces */
704 gst_caps_has_vaapi_surface (GstCaps * caps)
706 g_return_val_if_fail (caps != NULL, FALSE);
708 return _gst_caps_has_feature (caps, GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE);
712 gst_caps_is_video_raw (GstCaps * caps)
714 GstStructure *structure;
716 g_return_val_if_fail (caps != NULL, FALSE);
718 if (!gst_caps_is_fixed (caps))
720 if (!_gst_caps_has_feature (caps, GST_CAPS_FEATURE_MEMORY_SYSTEM_MEMORY))
722 structure = gst_caps_get_structure (caps, 0);
723 return gst_structure_has_name (structure, "video/x-raw");
727 gst_video_info_change_format (GstVideoInfo * vip, GstVideoFormat format,
728 guint width, guint height)
730 GstVideoInfo vi = *vip;
732 gst_video_info_set_format (vip, format, width, height);
734 GST_VIDEO_INFO_INTERLACE_MODE (vip) = GST_VIDEO_INFO_INTERLACE_MODE (&vi);
735 GST_VIDEO_FORMAT_INFO_FLAGS (vip) = GST_VIDEO_FORMAT_INFO_FLAGS (&vi);
736 GST_VIDEO_INFO_VIEWS (vip) = GST_VIDEO_INFO_VIEWS (&vi);
737 GST_VIDEO_INFO_PAR_N (vip) = GST_VIDEO_INFO_PAR_N (&vi);
738 GST_VIDEO_INFO_PAR_D (vip) = GST_VIDEO_INFO_PAR_D (&vi);
739 GST_VIDEO_INFO_FPS_N (vip) = GST_VIDEO_INFO_FPS_N (&vi);
740 GST_VIDEO_INFO_FPS_D (vip) = GST_VIDEO_INFO_FPS_D (&vi);
741 GST_VIDEO_INFO_MULTIVIEW_MODE (vip) = GST_VIDEO_INFO_MULTIVIEW_MODE (&vi);
742 GST_VIDEO_INFO_MULTIVIEW_FLAGS (vip) = GST_VIDEO_INFO_MULTIVIEW_FLAGS (&vi);
746 * gst_video_info_changed:
747 * @old: old #GstVideoInfo
748 * @new: new #GstVideoInfo
750 * Compares @old and @new
752 * Returns: %TRUE if @old has different format/width/height than
753 * @new. Otherwise, %FALSE.
756 gst_video_info_changed (const GstVideoInfo * old, const GstVideoInfo * new)
758 if (GST_VIDEO_INFO_FORMAT (old) != GST_VIDEO_INFO_FORMAT (new))
760 if (GST_VIDEO_INFO_WIDTH (old) != GST_VIDEO_INFO_WIDTH (new))
762 if (GST_VIDEO_INFO_HEIGHT (old) != GST_VIDEO_INFO_HEIGHT (new))
768 * gst_video_info_force_nv12_if_encoded:
769 * @vinfo: a #GstVideoInfo
771 * If the format of @vinfo is %GST_VIDEO_FORMAT_ENCODED it is changed
772 * to %GST_VIDEO_FORMAT_NV12.
775 gst_video_info_force_nv12_if_encoded (GstVideoInfo * vinfo)
777 if (GST_VIDEO_INFO_FORMAT (vinfo) != GST_VIDEO_FORMAT_ENCODED)
779 gst_video_info_set_format (vinfo, GST_VIDEO_FORMAT_NV12,
780 GST_VIDEO_INFO_WIDTH (vinfo), GST_VIDEO_INFO_HEIGHT (vinfo));
784 * gst_vaapi_create_test_display:
786 * Creates a temporal #GstVaapiDisplay instance, just for testing the
787 * supported features.
789 * Returns: a new #GstVaapiDisplay instances. Free with
790 * gst_vaapi_display_unref () after use.
793 gst_vaapi_create_test_display (void)
795 return gst_vaapi_create_display (GST_VAAPI_DISPLAY_TYPE_ANY, NULL);
799 * gst_vaapi_driver_is_whitelisted:
800 * @display: a #GstVaapiDisplay
802 * Looks the VA-API driver vendors in an internal white-list.
804 * Returns: %TRUE if driver is in the white-list, otherwise %FALSE
807 gst_vaapi_driver_is_whitelisted (GstVaapiDisplay * display)
811 static const gchar *whitelist[] = {
813 "mesa gallium vaapi",
817 g_return_val_if_fail (display, FALSE);
819 if (g_getenv (GST_VAAPI_ALL_DRIVERS_ENV))
822 vendor = gst_vaapi_display_get_vendor_string (display);
826 for (i = 0; whitelist[i]; i++) {
827 if (g_ascii_strncasecmp (vendor, whitelist[i], strlen (whitelist[i])) == 0)
831 GST_ERROR ("Unsupported VA driver: %s. Export environment variable "
832 GST_VAAPI_ALL_DRIVERS_ENV " to bypass", vendor);
838 GST_WARNING ("no VA-API driver vendor description");
844 * gst_vaapi_codecs_has_codec:
845 * @codecs: a #GArray of #GstVaapiCodec
846 * @codec: a #GstVaapiCodec to find in @codec
848 * Search in the available @codecs for the specific @codec.
850 * Returns: %TRUE if @codec is in @codecs
853 gst_vaapi_codecs_has_codec (GArray * codecs, GstVaapiCodec codec)
858 g_return_val_if_fail (codec, FALSE);
860 for (i = 0; i < codecs->len; i++) {
861 c = g_array_index (codecs, GstVaapiCodec, i);