2 * gstvaapidisplay.c - VA display abstraction
4 * Copyright (C) 2010-2011 Splitted-Desktop Systems
5 * Author: Gwenole Beauchesne <gwenole.beauchesne@splitted-desktop.com>
6 * Copyright (C) 2011-2013 Intel Corporation
7 * Author: Gwenole Beauchesne <gwenole.beauchesne@intel.com>
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
26 * SECTION:gstvaapidisplay
27 * @short_description: VA display abstraction
32 #include "gstvaapiutils.h"
33 #include "gstvaapivalue.h"
34 #include "gstvaapidisplay.h"
35 #include "gstvaapitexturemap.h"
36 #include "gstvaapidisplay_priv.h"
37 #include "gstvaapiworkarounds.h"
39 /* Debug category for all vaapi libs */
40 GST_DEBUG_CATEGORY (gst_debug_vaapi);
42 /* Debug category for VaapiDisplay */
43 GST_DEBUG_CATEGORY (gst_debug_vaapi_display);
44 #define GST_CAT_DEFAULT gst_debug_vaapi_display
47 G_ADD_PRIVATE (GstVaapiDisplay); \
48 GST_DEBUG_CATEGORY_INIT (gst_debug_vaapi_display, \
49 "vaapidisplay", 0, "VA-API Display");
51 G_DEFINE_TYPE_WITH_CODE (GstVaapiDisplay, gst_vaapi_display, GST_TYPE_OBJECT,
54 /* Ensure those symbols are actually defined in the resulting libraries */
55 #undef gst_vaapi_display_ref
56 #undef gst_vaapi_display_unref
57 #undef gst_vaapi_display_replace
59 typedef struct _GstVaapiConfig GstVaapiConfig;
60 struct _GstVaapiConfig
62 GstVaapiProfile profile;
63 GstVaapiEntrypoint entrypoint;
66 typedef struct _GstVaapiProperty GstVaapiProperty;
67 struct _GstVaapiProperty
70 VADisplayAttribute attribute;
74 typedef struct _GstVaapiFormatInfo GstVaapiFormatInfo;
75 struct _GstVaapiFormatInfo
77 GstVideoFormat format;
81 #define DEFAULT_RENDER_MODE GST_VAAPI_RENDER_MODE_TEXTURE
82 #define DEFAULT_ROTATION GST_VAAPI_ROTATION_0
98 static GParamSpec *g_properties[N_PROPERTIES] = { NULL, };
100 static void gst_vaapi_display_properties_init (void);
103 get_attribute (GstVaapiDisplay * display, VADisplayAttribType type,
107 set_attribute (GstVaapiDisplay * display, VADisplayAttribType type, gint value);
110 get_color_balance (GstVaapiDisplay * display, guint prop_id, gfloat * v);
113 set_color_balance (GstVaapiDisplay * display, guint prop_id, gfloat v);
116 libgstvaapi_init_once (void)
118 static gsize g_once = FALSE;
120 if (!g_once_init_enter (&g_once))
123 GST_DEBUG_CATEGORY_INIT (gst_debug_vaapi, "vaapi", 0, "VA-API helper");
125 gst_vaapi_display_properties_init ();
127 g_once_init_leave (&g_once, TRUE);
130 /* GstVaapiDisplayType enumerations */
132 gst_vaapi_display_type_get_type (void)
134 static GType g_type = 0;
136 static const GEnumValue display_types[] = {
137 {GST_VAAPI_DISPLAY_TYPE_ANY,
138 "Auto detection", "any"},
140 {GST_VAAPI_DISPLAY_TYPE_X11,
141 "VA/X11 display", "x11"},
144 {GST_VAAPI_DISPLAY_TYPE_GLX,
145 "VA/GLX display", "glx"},
148 {GST_VAAPI_DISPLAY_TYPE_EGL,
149 "VA/EGL display", "egl"},
152 {GST_VAAPI_DISPLAY_TYPE_WAYLAND,
153 "VA/Wayland display", "wayland"},
156 {GST_VAAPI_DISPLAY_TYPE_DRM,
157 "VA/DRM display", "drm"},
163 g_type = g_enum_register_static ("GstVaapiDisplayType", display_types);
168 * gst_vaapi_display_type_is_compatible:
169 * @type1: the #GstVaapiDisplayType to test
170 * @type2: the reference #GstVaapiDisplayType
172 * Compares whether #GstVaapiDisplay @type1 is compatible with @type2.
173 * That is, if @type2 is in "any" category, or derived from @type1.
175 * Returns: %TRUE if @type1 is compatible with @type2, %FALSE otherwise.
178 gst_vaapi_display_type_is_compatible (GstVaapiDisplayType type1,
179 GstVaapiDisplayType type2)
185 case GST_VAAPI_DISPLAY_TYPE_GLX:
186 if (type2 == GST_VAAPI_DISPLAY_TYPE_X11)
192 return type2 == GST_VAAPI_DISPLAY_TYPE_ANY;
195 /* Append GstVideoFormat to formats array */
197 append_format (GArray * formats, GstVideoFormat format, guint flags)
199 GstVaapiFormatInfo fi;
203 g_array_append_val (formats, fi);
206 /* Append VAImageFormats to formats array */
208 append_formats (GArray * formats, const VAImageFormat * va_formats,
209 guint * flags, guint n)
211 GstVideoFormat format;
212 const GstVaapiFormatInfo *YV12_fip = NULL;
213 const GstVaapiFormatInfo *I420_fip = NULL;
216 for (i = 0; i < n; i++) {
217 const VAImageFormat *const va_format = &va_formats[i];
218 const GstVaapiFormatInfo **fipp;
220 format = gst_vaapi_video_format_from_va_format (va_format);
221 if (format == GST_VIDEO_FORMAT_UNKNOWN) {
222 GST_DEBUG ("unsupported format %" GST_FOURCC_FORMAT,
223 GST_FOURCC_ARGS (va_format->fourcc));
226 append_format (formats, format, flags ? flags[i] : 0);
229 case GST_VIDEO_FORMAT_YV12:
232 case GST_VIDEO_FORMAT_I420:
240 *fipp = &g_array_index (formats, GstVaapiFormatInfo, formats->len - 1);
243 /* Append I420 (resp. YV12) format if YV12 (resp. I420) is not
244 supported by the underlying driver */
245 if (YV12_fip && !I420_fip)
246 append_format (formats, GST_VIDEO_FORMAT_I420, YV12_fip->flags);
247 else if (I420_fip && !YV12_fip)
248 append_format (formats, GST_VIDEO_FORMAT_YV12, I420_fip->flags);
251 /* Sort image formats. Prefer YUV formats first */
253 compare_yuv_formats (gconstpointer a, gconstpointer b)
255 const GstVideoFormat fmt1 = ((GstVaapiFormatInfo *) a)->format;
256 const GstVideoFormat fmt2 = ((GstVaapiFormatInfo *) b)->format;
258 const gboolean is_fmt1_yuv = gst_vaapi_video_format_is_yuv (fmt1);
259 const gboolean is_fmt2_yuv = gst_vaapi_video_format_is_yuv (fmt2);
261 if (is_fmt1_yuv != is_fmt2_yuv)
262 return is_fmt1_yuv ? -1 : 1;
264 return ((gint) gst_vaapi_video_format_get_score (fmt1) -
265 (gint) gst_vaapi_video_format_get_score (fmt2));
268 /* Sort subpicture formats. Prefer RGB formats first */
270 compare_rgb_formats (gconstpointer a, gconstpointer b)
272 const GstVideoFormat fmt1 = ((GstVaapiFormatInfo *) a)->format;
273 const GstVideoFormat fmt2 = ((GstVaapiFormatInfo *) b)->format;
275 const gboolean is_fmt1_rgb = gst_vaapi_video_format_is_rgb (fmt1);
276 const gboolean is_fmt2_rgb = gst_vaapi_video_format_is_rgb (fmt2);
278 if (is_fmt1_rgb != is_fmt2_rgb)
279 return is_fmt1_rgb ? -1 : 1;
281 return ((gint) gst_vaapi_video_format_get_score (fmt1) -
282 (gint) gst_vaapi_video_format_get_score (fmt2));
285 /* Check if configs array contains profile at entrypoint */
286 static inline gboolean
287 find_config (GArray * configs,
288 GstVaapiProfile profile, GstVaapiEntrypoint entrypoint)
290 GstVaapiConfig *config;
296 for (i = 0; i < configs->len; i++) {
297 config = &g_array_index (configs, GstVaapiConfig, i);
298 if (config->profile == profile && config->entrypoint == entrypoint)
304 /* HACK: append H.263 Baseline profile if MPEG-4:2 Simple profile is supported */
306 append_h263_config (GArray * configs)
308 GstVaapiConfig *config, tmp_config;
309 GstVaapiConfig *mpeg4_simple_config = NULL;
310 GstVaapiConfig *h263_baseline_config = NULL;
313 if (!WORKAROUND_H263_BASELINE_DECODE_PROFILE)
319 for (i = 0; i < configs->len; i++) {
320 config = &g_array_index (configs, GstVaapiConfig, i);
321 if (config->profile == GST_VAAPI_PROFILE_MPEG4_SIMPLE)
322 mpeg4_simple_config = config;
323 else if (config->profile == GST_VAAPI_PROFILE_H263_BASELINE)
324 h263_baseline_config = config;
327 if (mpeg4_simple_config && !h263_baseline_config) {
328 tmp_config = *mpeg4_simple_config;
329 tmp_config.profile = GST_VAAPI_PROFILE_H263_BASELINE;
330 g_array_append_val (configs, tmp_config);
334 /* Sort profiles. Group per codec */
336 compare_profiles (gconstpointer a, gconstpointer b)
338 const GstVaapiConfig *const config1 = (GstVaapiConfig *) a;
339 const GstVaapiConfig *const config2 = (GstVaapiConfig *) b;
341 if (config1->profile == config2->profile)
342 return config1->entrypoint - config2->entrypoint;
344 return config1->profile - config2->profile;
347 /* Convert configs array to profiles as GstCaps */
349 get_profiles (GArray * configs)
351 GstVaapiConfig *config;
352 GArray *out_profiles;
358 out_profiles = g_array_new (FALSE, FALSE, sizeof (GstVaapiProfile));
362 for (i = 0; i < configs->len; i++) {
363 config = &g_array_index (configs, GstVaapiConfig, i);
364 g_array_append_val (out_profiles, config->profile);
369 /* Find format info */
370 static const GstVaapiFormatInfo *
371 find_format_info (GArray * formats, GstVideoFormat format)
373 const GstVaapiFormatInfo *fip;
376 for (i = 0; i < formats->len; i++) {
377 fip = &g_array_index (formats, GstVaapiFormatInfo, i);
378 if (fip->format == format)
384 /* Check if formats array contains format */
385 static inline gboolean
386 find_format (GArray * formats, GstVideoFormat format)
388 return find_format_info (formats, format) != NULL;
391 /* Convert formats array to GstCaps */
393 get_formats (GArray * formats)
395 const GstVaapiFormatInfo *fip;
399 out_formats = g_array_new (FALSE, FALSE, sizeof (GstVideoFormat));
403 for (i = 0; i < formats->len; i++) {
404 fip = &g_array_index (formats, GstVaapiFormatInfo, i);
405 g_array_append_val (out_formats, fip->format);
410 /* Find display attribute */
411 static const GstVaapiProperty *
412 find_property (GArray * properties, const gchar * name)
414 GstVaapiProperty *prop;
420 for (i = 0; i < properties->len; i++) {
421 prop = &g_array_index (properties, GstVaapiProperty, i);
422 if (strcmp (prop->name, name) == 0)
429 static const GstVaapiProperty *
430 find_property_by_type (GArray * properties, VADisplayAttribType type)
432 GstVaapiProperty *prop;
435 for (i = 0; i < properties->len; i++) {
436 prop = &g_array_index (properties, GstVaapiProperty, i);
437 if (prop->attribute.type == type)
444 static inline const GstVaapiProperty *
445 find_property_by_pspec (GstVaapiDisplay * display, GParamSpec * pspec)
447 GstVaapiDisplayPrivate *const priv = GST_VAAPI_DISPLAY_GET_PRIVATE (display);
449 return find_property (priv->properties, pspec->name);
453 find_property_id (const gchar * name)
461 static const property_map g_property_map[] = {
462 {GST_VAAPI_DISPLAY_PROP_RENDER_MODE, PROP_RENDER_MODE},
463 {GST_VAAPI_DISPLAY_PROP_ROTATION, PROP_ROTATION},
464 {GST_VAAPI_DISPLAY_PROP_HUE, PROP_HUE},
465 {GST_VAAPI_DISPLAY_PROP_SATURATION, PROP_SATURATION},
466 {GST_VAAPI_DISPLAY_PROP_BRIGHTNESS, PROP_BRIGHTNESS},
467 {GST_VAAPI_DISPLAY_PROP_CONTRAST, PROP_CONTRAST},
471 const property_map *m;
472 for (m = g_property_map; m->name != NULL; m++) {
473 if (strcmp (m->name, name) == 0)
479 /* Initialize VA profiles (decoders, encoders) */
481 ensure_profiles (GstVaapiDisplay * display)
483 GstVaapiDisplayPrivate *const priv = GST_VAAPI_DISPLAY_GET_PRIVATE (display);
484 VAProfile *profiles = NULL;
485 VAEntrypoint *entrypoints = NULL;
486 gint i, j, n, num_entrypoints;
488 gboolean success = FALSE;
490 if (priv->has_profiles)
493 priv->decoders = g_array_new (FALSE, FALSE, sizeof (GstVaapiConfig));
496 priv->encoders = g_array_new (FALSE, FALSE, sizeof (GstVaapiConfig));
499 priv->has_profiles = TRUE;
502 profiles = g_new (VAProfile, vaMaxNumProfiles (priv->display));
505 entrypoints = g_new (VAEntrypoint, vaMaxNumEntrypoints (priv->display));
510 status = vaQueryConfigProfiles (priv->display, profiles, &n);
511 if (!vaapi_check_status (status, "vaQueryConfigProfiles()"))
514 GST_DEBUG ("%d profiles", n);
515 for (i = 0; i < n; i++) {
516 #if VA_CHECK_VERSION(0,34,0)
517 /* Introduced in VA/VPP API */
518 if (profiles[i] == VAProfileNone)
521 GST_DEBUG (" %s", string_of_VAProfile (profiles[i]));
524 for (i = 0; i < n; i++) {
525 GstVaapiConfig config;
527 config.profile = gst_vaapi_profile (profiles[i]);
531 status = vaQueryConfigEntrypoints (priv->display,
532 profiles[i], entrypoints, &num_entrypoints);
533 if (!vaapi_check_status (status, "vaQueryConfigEntrypoints()"))
536 for (j = 0; j < num_entrypoints; j++) {
537 config.entrypoint = gst_vaapi_entrypoint (entrypoints[j]);
538 switch (config.entrypoint) {
539 case GST_VAAPI_ENTRYPOINT_VLD:
540 case GST_VAAPI_ENTRYPOINT_IDCT:
541 case GST_VAAPI_ENTRYPOINT_MOCO:
542 g_array_append_val (priv->decoders, config);
544 case GST_VAAPI_ENTRYPOINT_SLICE_ENCODE:
545 case GST_VAAPI_ENTRYPOINT_PICTURE_ENCODE:
546 case GST_VAAPI_ENTRYPOINT_SLICE_ENCODE_LP:
547 g_array_append_val (priv->encoders, config);
552 append_h263_config (priv->decoders);
554 g_array_sort (priv->decoders, compare_profiles);
555 g_array_sort (priv->encoders, compare_profiles);
557 /* Video processing API */
559 status = vaQueryConfigEntrypoints (priv->display, VAProfileNone,
560 entrypoints, &num_entrypoints);
561 if (vaapi_check_status (status, "vaQueryEntrypoints() [VAProfileNone]")) {
562 for (j = 0; j < num_entrypoints; j++) {
563 if (entrypoints[j] == VAEntrypointVideoProc)
564 priv->has_vpp = TRUE;
572 g_free (entrypoints);
576 /* Initialize VA display attributes */
578 ensure_properties (GstVaapiDisplay * display)
580 GstVaapiDisplayPrivate *const priv = GST_VAAPI_DISPLAY_GET_PRIVATE (display);
581 VADisplayAttribute *display_attrs = NULL;
584 gboolean success = FALSE;
586 if (priv->properties)
589 priv->properties = g_array_new (FALSE, FALSE, sizeof (GstVaapiProperty));
590 if (!priv->properties)
593 /* VA display attributes */
595 g_new (VADisplayAttribute, vaMaxNumDisplayAttributes (priv->display));
600 status = vaQueryDisplayAttributes (priv->display, display_attrs, &n);
601 if (!vaapi_check_status (status, "vaQueryDisplayAttributes()"))
604 GST_DEBUG ("%d display attributes", n);
605 for (i = 0; i < n; i++) {
606 VADisplayAttribute *const attr = &display_attrs[i];
607 GstVaapiProperty prop;
610 GST_DEBUG (" %s", string_of_VADisplayAttributeType (attr->type));
612 switch (attr->type) {
613 #if !VA_CHECK_VERSION(0,34,0)
614 case VADisplayAttribDirectSurface:
615 prop.name = GST_VAAPI_DISPLAY_PROP_RENDER_MODE;
618 case VADisplayAttribRenderMode:
619 prop.name = GST_VAAPI_DISPLAY_PROP_RENDER_MODE;
621 case VADisplayAttribRotation:
622 prop.name = GST_VAAPI_DISPLAY_PROP_ROTATION;
624 case VADisplayAttribHue:
625 prop.name = GST_VAAPI_DISPLAY_PROP_HUE;
627 case VADisplayAttribSaturation:
628 prop.name = GST_VAAPI_DISPLAY_PROP_SATURATION;
630 case VADisplayAttribBrightness:
631 prop.name = GST_VAAPI_DISPLAY_PROP_BRIGHTNESS;
633 case VADisplayAttribContrast:
634 prop.name = GST_VAAPI_DISPLAY_PROP_CONTRAST;
643 /* Assume the attribute is really supported if we can get the
644 * actual and current value */
645 if (!get_attribute (display, attr->type, &value))
648 /* Some drivers (e.g. EMGD) have completely random initial
650 if (value < attr->min_value || value > attr->max_value)
653 prop.attribute = *attr;
654 prop.old_value = value;
655 g_array_append_val (priv->properties, prop);
660 g_free (display_attrs);
664 /* Initialize VA image formats */
666 ensure_image_formats (GstVaapiDisplay * display)
668 GstVaapiDisplayPrivate *const priv = GST_VAAPI_DISPLAY_GET_PRIVATE (display);
669 VAImageFormat *formats = NULL;
672 gboolean success = FALSE;
674 if (priv->image_formats)
677 priv->image_formats = g_array_new (FALSE, FALSE, sizeof (GstVaapiFormatInfo));
678 if (!priv->image_formats)
681 /* VA image formats */
682 formats = g_new (VAImageFormat, vaMaxNumImageFormats (priv->display));
687 status = vaQueryImageFormats (priv->display, formats, &n);
688 if (!vaapi_check_status (status, "vaQueryImageFormats()"))
691 GST_DEBUG ("%d image formats", n);
692 for (i = 0; i < n; i++)
693 GST_DEBUG (" %" GST_FOURCC_FORMAT, GST_FOURCC_ARGS (formats[i].fourcc));
695 append_formats (priv->image_formats, formats, NULL, n);
696 g_array_sort (priv->image_formats, compare_yuv_formats);
704 /* Initialize VA subpicture formats */
706 ensure_subpicture_formats (GstVaapiDisplay * display)
708 GstVaapiDisplayPrivate *const priv = GST_VAAPI_DISPLAY_GET_PRIVATE (display);
709 VAImageFormat *formats = NULL;
710 unsigned int *flags = NULL;
713 gboolean success = FALSE;
715 if (priv->subpicture_formats)
718 priv->subpicture_formats =
719 g_array_new (FALSE, FALSE, sizeof (GstVaapiFormatInfo));
720 if (!priv->subpicture_formats)
723 /* VA subpicture formats */
724 n = vaMaxNumSubpictureFormats (priv->display);
725 formats = g_new (VAImageFormat, n);
728 flags = g_new (guint, n);
733 status = vaQuerySubpictureFormats (priv->display, formats, flags, &n);
734 if (!vaapi_check_status (status, "vaQuerySubpictureFormats()"))
737 GST_DEBUG ("%d subpicture formats", n);
738 for (i = 0; i < n; i++) {
739 GST_DEBUG (" %" GST_FOURCC_FORMAT, GST_FOURCC_ARGS (formats[i].fourcc));
740 flags[i] = to_GstVaapiSubpictureFlags (flags[i]);
743 append_formats (priv->subpicture_formats, formats, flags, n);
744 g_array_sort (priv->subpicture_formats, compare_rgb_formats);
754 gst_vaapi_display_calculate_pixel_aspect_ratio (GstVaapiDisplay * display)
756 GstVaapiDisplayPrivate *const priv = GST_VAAPI_DISPLAY_GET_PRIVATE (display);
757 gdouble ratio, delta;
758 gint i, j, index, windex;
760 static const gint par[][2] = {
761 {1, 1}, /* regular screen */
762 {16, 15}, /* PAL TV */
763 {11, 10}, /* 525 line Rec.601 video */
764 {54, 59}, /* 625 line Rec.601 video */
765 {64, 45}, /* 1280x1024 on 16:9 display */
766 {5, 3}, /* 1280x1024 on 4:3 display */
767 {4, 3} /* 800x600 on 16:9 display */
770 /* First, calculate the "real" ratio based on the X values;
771 * which is the "physical" w/h divided by the w/h in pixels of the
773 if (!priv->width || !priv->height || !priv->width_mm || !priv->height_mm)
776 ratio = (gdouble) (priv->width_mm * priv->height) /
777 (priv->height_mm * priv->width);
778 GST_DEBUG ("calculated pixel aspect ratio: %f", ratio);
780 /* Now, find the one from par[][2] with the lowest delta to the real one */
781 #define DELTA(idx, w) (ABS(ratio - ((gdouble)par[idx][w] / par[idx][!(w)])))
782 delta = DELTA (0, 0);
786 for (i = 1; i < G_N_ELEMENTS (par); i++) {
787 for (j = 0; j < 2; j++) {
788 const gdouble this_delta = DELTA (i, j);
789 if (this_delta < delta) {
798 priv->par_n = par[index][windex];
799 priv->par_d = par[index][windex ^ 1];
803 gst_vaapi_display_destroy (GstVaapiDisplay * display)
805 GstVaapiDisplayPrivate *const priv = GST_VAAPI_DISPLAY_GET_PRIVATE (display);
807 if (priv->decoders) {
808 g_array_free (priv->decoders, TRUE);
809 priv->decoders = NULL;
812 if (priv->encoders) {
813 g_array_free (priv->encoders, TRUE);
814 priv->encoders = NULL;
817 if (priv->image_formats) {
818 g_array_free (priv->image_formats, TRUE);
819 priv->image_formats = NULL;
822 if (priv->subpicture_formats) {
823 g_array_free (priv->subpicture_formats, TRUE);
824 priv->subpicture_formats = NULL;
827 if (priv->properties) {
828 g_array_free (priv->properties, TRUE);
829 priv->properties = NULL;
834 vaTerminate (priv->display);
835 priv->display = NULL;
838 if (!priv->use_foreign_display) {
839 GstVaapiDisplayClass *klass = GST_VAAPI_DISPLAY_GET_CLASS (display);
840 if (klass->close_display)
841 klass->close_display (display);
844 g_free (priv->display_name);
845 priv->display_name = NULL;
847 g_free (priv->vendor_string);
848 priv->vendor_string = NULL;
850 gst_vaapi_display_replace_internal (&priv->parent, NULL);
854 gst_vaapi_display_create_unlocked (GstVaapiDisplay * display,
855 GstVaapiDisplayInitType init_type, gpointer init_value)
857 GstVaapiDisplayPrivate *const priv = GST_VAAPI_DISPLAY_GET_PRIVATE (display);
858 const GstVaapiDisplayClass *const klass =
859 GST_VAAPI_DISPLAY_GET_CLASS (display);
860 GstVaapiDisplayInfo info;
862 memset (&info, 0, sizeof (info));
863 info.display = display;
864 info.display_type = priv->display_type;
867 case GST_VAAPI_DISPLAY_INIT_FROM_VA_DISPLAY:
868 info.va_display = init_value;
869 priv->display = init_value;
870 priv->use_foreign_display = TRUE;
872 case GST_VAAPI_DISPLAY_INIT_FROM_DISPLAY_NAME:
873 if (klass->open_display && !klass->open_display (display, init_value))
876 case GST_VAAPI_DISPLAY_INIT_FROM_NATIVE_DISPLAY:
877 if (klass->bind_display && !klass->bind_display (display, init_value))
881 if (!klass->get_display || !klass->get_display (display, &info))
883 priv->display = info.va_display;
884 priv->display_type = info.display_type;
885 priv->native_display = info.native_display;
887 klass->get_size (display, &priv->width, &priv->height);
888 if (klass->get_size_mm)
889 klass->get_size_mm (display, &priv->width_mm, &priv->height_mm);
890 gst_vaapi_display_calculate_pixel_aspect_ratio (display);
897 if (!vaapi_initialize (priv->display))
901 GST_INFO_OBJECT (display, "new display addr=%p", display);
902 g_free (priv->display_name);
903 priv->display_name = g_strdup (info.display_name);
908 gst_vaapi_display_create (GstVaapiDisplay * display,
909 GstVaapiDisplayInitType init_type, gpointer init_value)
911 return gst_vaapi_display_create_unlocked (display, init_type, init_value);
915 gst_vaapi_display_lock_default (GstVaapiDisplay * display)
917 GstVaapiDisplayPrivate *priv = GST_VAAPI_DISPLAY_GET_PRIVATE (display);
920 priv = GST_VAAPI_DISPLAY_GET_PRIVATE (priv->parent);
921 g_rec_mutex_lock (&priv->mutex);
925 gst_vaapi_display_unlock_default (GstVaapiDisplay * display)
927 GstVaapiDisplayPrivate *priv = GST_VAAPI_DISPLAY_GET_PRIVATE (display);
930 priv = GST_VAAPI_DISPLAY_GET_PRIVATE (priv->parent);
931 g_rec_mutex_unlock (&priv->mutex);
935 gst_vaapi_display_init (GstVaapiDisplay * display)
937 GstVaapiDisplayPrivate *const priv =
938 gst_vaapi_display_get_instance_private (display);
940 display->priv = priv;
941 priv->display_type = GST_VAAPI_DISPLAY_TYPE_ANY;
945 g_rec_mutex_init (&priv->mutex);
949 gst_vaapi_display_finalize (GObject * object)
951 GstVaapiDisplay *const display = GST_VAAPI_DISPLAY (object);
952 GstVaapiDisplayPrivate *const priv = GST_VAAPI_DISPLAY_GET_PRIVATE (display);
954 gst_vaapi_display_destroy (display);
955 g_rec_mutex_clear (&priv->mutex);
957 G_OBJECT_CLASS (gst_vaapi_display_parent_class)->finalize (object);
961 gst_vaapi_display_class_init (GstVaapiDisplayClass * klass)
963 GObjectClass *const object_class = G_OBJECT_CLASS (klass);
965 libgstvaapi_init_once ();
967 object_class->finalize = gst_vaapi_display_finalize;
968 klass->lock = gst_vaapi_display_lock_default;
969 klass->unlock = gst_vaapi_display_unlock_default;
973 gst_vaapi_display_properties_init (void)
976 * GstVaapiDisplay:render-mode:
978 * The VA display rendering mode, expressed as a #GstVaapiRenderMode.
980 g_properties[PROP_RENDER_MODE] =
981 g_param_spec_enum (GST_VAAPI_DISPLAY_PROP_RENDER_MODE,
983 "The display rendering mode",
984 GST_VAAPI_TYPE_RENDER_MODE, DEFAULT_RENDER_MODE, G_PARAM_READWRITE);
987 * GstVaapiDisplay:rotation:
989 * The VA display rotation mode, expressed as a #GstVaapiRotation.
991 g_properties[PROP_ROTATION] =
992 g_param_spec_enum (GST_VAAPI_DISPLAY_PROP_ROTATION,
994 "The display rotation mode",
995 GST_VAAPI_TYPE_ROTATION, DEFAULT_ROTATION, G_PARAM_READWRITE);
998 * GstVaapiDisplay:hue:
1000 * The VA display hue, expressed as a float value. Range is -180.0
1001 * to 180.0. Default value is 0.0 and represents no modification.
1003 g_properties[PROP_HUE] =
1004 g_param_spec_float (GST_VAAPI_DISPLAY_PROP_HUE,
1005 "hue", "The display hue value", -180.0, 180.0, 0.0, G_PARAM_READWRITE);
1008 * GstVaapiDisplay:saturation:
1010 * The VA display saturation, expressed as a float value. Range is
1011 * 0.0 to 2.0. Default value is 1.0 and represents no modification.
1013 g_properties[PROP_SATURATION] =
1014 g_param_spec_float (GST_VAAPI_DISPLAY_PROP_SATURATION,
1016 "The display saturation value", 0.0, 2.0, 1.0, G_PARAM_READWRITE);
1019 * GstVaapiDisplay:brightness:
1021 * The VA display brightness, expressed as a float value. Range is
1022 * -1.0 to 1.0. Default value is 0.0 and represents no modification.
1024 g_properties[PROP_BRIGHTNESS] =
1025 g_param_spec_float (GST_VAAPI_DISPLAY_PROP_BRIGHTNESS,
1027 "The display brightness value", -1.0, 1.0, 0.0, G_PARAM_READWRITE);
1030 * GstVaapiDisplay:contrast:
1032 * The VA display contrast, expressed as a float value. Range is 0.0
1033 * to 2.0. Default value is 1.0 and represents no modification.
1035 g_properties[PROP_CONTRAST] =
1036 g_param_spec_float (GST_VAAPI_DISPLAY_PROP_CONTRAST,
1038 "The display contrast value", 0.0, 2.0, 1.0, G_PARAM_READWRITE);
1042 gst_vaapi_display_new (GstVaapiDisplay * display,
1043 GstVaapiDisplayInitType init_type, gpointer init_value)
1045 g_return_val_if_fail (display != NULL, NULL);
1047 if (!gst_vaapi_display_create (display, init_type, init_value))
1054 gst_vaapi_display_unref_internal (display);
1060 * gst_vaapi_display_new_with_display:
1061 * @va_display: a #VADisplay
1063 * Creates a new #GstVaapiDisplay, using @va_display as the VA
1066 * Return value: the newly created #GstVaapiDisplay object
1069 gst_vaapi_display_new_with_display (VADisplay va_display)
1071 return gst_vaapi_display_new (g_object_new (GST_TYPE_VAAPI_DISPLAY, NULL),
1072 GST_VAAPI_DISPLAY_INIT_FROM_VA_DISPLAY, va_display);
1076 * gst_vaapi_display_ref:
1077 * @display: a #GstVaapiDisplay
1079 * Atomically increases the reference count of the given @display by one.
1081 * Returns: The same @display argument
1084 gst_vaapi_display_ref (GstVaapiDisplay * display)
1086 return gst_vaapi_display_ref_internal (display);
1090 * gst_vaapi_display_unref:
1091 * @display: a #GstVaapiDisplay
1093 * Atomically decreases the reference count of the @display by one. If
1094 * the reference count reaches zero, the display will be free'd.
1097 gst_vaapi_display_unref (GstVaapiDisplay * display)
1099 gst_vaapi_display_unref_internal (display);
1103 * gst_vaapi_display_replace:
1104 * @old_display_ptr: a pointer to a #GstVaapiDisplay
1105 * @new_display: a #GstVaapiDisplay
1107 * Atomically replaces the display display held in @old_display_ptr
1108 * with @new_display. This means that @old_display_ptr shall reference
1109 * a valid display. However, @new_display can be NULL.
1112 gst_vaapi_display_replace (GstVaapiDisplay ** old_display_ptr,
1113 GstVaapiDisplay * new_display)
1115 gst_vaapi_display_replace_internal (old_display_ptr, new_display);
1119 * gst_vaapi_display_lock:
1120 * @display: a #GstVaapiDisplay
1122 * Locks @display. If @display is already locked by another thread,
1123 * the current thread will block until @display is unlocked by the
1127 gst_vaapi_display_lock (GstVaapiDisplay * display)
1129 GstVaapiDisplayClass *klass;
1131 g_return_if_fail (display != NULL);
1133 klass = GST_VAAPI_DISPLAY_GET_CLASS (display);
1135 klass->lock (display);
1139 * gst_vaapi_display_unlock:
1140 * @display: a #GstVaapiDisplay
1142 * Unlocks @display. If another thread is blocked in a
1143 * gst_vaapi_display_lock() call for @display, it will be woken and
1144 * can lock @display itself.
1147 gst_vaapi_display_unlock (GstVaapiDisplay * display)
1149 GstVaapiDisplayClass *klass;
1151 g_return_if_fail (display != NULL);
1153 klass = GST_VAAPI_DISPLAY_GET_CLASS (display);
1155 klass->unlock (display);
1159 * gst_vaapi_display_sync:
1160 * @display: a #GstVaapiDisplay
1162 * Flushes any requests queued for the windowing system and waits until
1163 * all requests have been handled. This is often used for making sure
1164 * that the display is synchronized with the current state of the program.
1166 * This is most useful for X11. On windowing systems where requests are
1167 * handled synchronously, this function will do nothing.
1170 gst_vaapi_display_sync (GstVaapiDisplay * display)
1172 GstVaapiDisplayClass *klass;
1174 g_return_if_fail (display != NULL);
1176 klass = GST_VAAPI_DISPLAY_GET_CLASS (display);
1178 klass->sync (display);
1179 else if (klass->flush)
1180 klass->flush (display);
1184 * gst_vaapi_display_flush:
1185 * @display: a #GstVaapiDisplay
1187 * Flushes any requests queued for the windowing system.
1189 * This is most useful for X11. On windowing systems where requests
1190 * are handled synchronously, this function will do nothing.
1193 gst_vaapi_display_flush (GstVaapiDisplay * display)
1195 GstVaapiDisplayClass *klass;
1197 g_return_if_fail (display != NULL);
1199 klass = GST_VAAPI_DISPLAY_GET_CLASS (display);
1201 klass->flush (display);
1205 * gst_vaapi_display_get_class_type:
1206 * @display: a #GstVaapiDisplay
1208 * Returns the #GstVaapiDisplayType of @display. This is the type of
1209 * the object, thus the associated class, not the type of the VA
1212 * Return value: the #GstVaapiDisplayType
1215 gst_vaapi_display_get_class_type (GstVaapiDisplay * display)
1217 g_return_val_if_fail (display != NULL, GST_VAAPI_DISPLAY_TYPE_ANY);
1219 return GST_VAAPI_DISPLAY_GET_CLASS_TYPE (display);
1223 * gst_vaapi_display_get_display_type:
1224 * @display: a #GstVaapiDisplay
1226 * Returns the #GstVaapiDisplayType of the VA display bound to
1227 * @display. This is not the type of the @display object.
1229 * Return value: the #GstVaapiDisplayType
1232 gst_vaapi_display_get_display_type (GstVaapiDisplay * display)
1234 g_return_val_if_fail (display != NULL, GST_VAAPI_DISPLAY_TYPE_ANY);
1236 return GST_VAAPI_DISPLAY_VADISPLAY_TYPE (display);
1240 * gst_vaapi_display_get_display_type:
1241 * @display: a #GstVaapiDisplay
1243 * Returns the @display name.
1245 * Return value: the display name
1248 gst_vaapi_display_get_display_name (GstVaapiDisplay * display)
1250 g_return_val_if_fail (display != NULL, NULL);
1252 return GST_VAAPI_DISPLAY_GET_PRIVATE (display)->display_name;
1256 * gst_vaapi_display_get_display:
1257 * @display: a #GstVaapiDisplay
1259 * Returns the #VADisplay bound to @display.
1261 * Return value: the #VADisplay
1264 gst_vaapi_display_get_display (GstVaapiDisplay * display)
1266 g_return_val_if_fail (display != NULL, NULL);
1268 return GST_VAAPI_DISPLAY_GET_PRIVATE (display)->display;
1272 * gst_vaapi_display_get_width:
1273 * @display: a #GstVaapiDisplay
1275 * Retrieves the width of a #GstVaapiDisplay.
1277 * Return value: the width of the @display, in pixels
1280 gst_vaapi_display_get_width (GstVaapiDisplay * display)
1282 g_return_val_if_fail (display != NULL, 0);
1284 return GST_VAAPI_DISPLAY_GET_PRIVATE (display)->width;
1288 * gst_vaapi_display_get_height:
1289 * @display: a #GstVaapiDisplay
1291 * Retrieves the height of a #GstVaapiDisplay
1293 * Return value: the height of the @display, in pixels
1296 gst_vaapi_display_get_height (GstVaapiDisplay * display)
1298 g_return_val_if_fail (display != NULL, 0);
1300 return GST_VAAPI_DISPLAY_GET_PRIVATE (display)->height;
1304 * gst_vaapi_display_get_size:
1305 * @display: a #GstVaapiDisplay
1306 * @pwidth: return location for the width, or %NULL
1307 * @pheight: return location for the height, or %NULL
1309 * Retrieves the dimensions of a #GstVaapiDisplay.
1312 gst_vaapi_display_get_size (GstVaapiDisplay * display, guint * pwidth,
1315 g_return_if_fail (GST_VAAPI_DISPLAY (display));
1318 *pwidth = GST_VAAPI_DISPLAY_GET_PRIVATE (display)->width;
1321 *pheight = GST_VAAPI_DISPLAY_GET_PRIVATE (display)->height;
1325 * gst_vaapi_display_get_pixel_aspect_ratio:
1326 * @display: a #GstVaapiDisplay
1327 * @par_n: return location for the numerator of pixel aspect ratio, or %NULL
1328 * @par_d: return location for the denominator of pixel aspect ratio, or %NULL
1330 * Retrieves the pixel aspect ratio of a #GstVaapiDisplay.
1333 gst_vaapi_display_get_pixel_aspect_ratio (GstVaapiDisplay * display,
1334 guint * par_n, guint * par_d)
1336 g_return_if_fail (display != NULL);
1339 *par_n = GST_VAAPI_DISPLAY_GET_PRIVATE (display)->par_n;
1342 *par_d = GST_VAAPI_DISPLAY_GET_PRIVATE (display)->par_d;
1346 * gst_vaapi_display_has_video_processing:
1347 * @display: a #GstVaapiDisplay
1349 * Checks whether the underlying VA driver implementation supports
1350 * video processing (VPP) acceleration.
1352 * Returns: %TRUE if some VPP features are available
1355 gst_vaapi_display_has_video_processing (GstVaapiDisplay * display)
1357 g_return_val_if_fail (display != NULL, FALSE);
1359 if (!ensure_profiles (display))
1361 return GST_VAAPI_DISPLAY_GET_PRIVATE (display)->has_vpp;
1365 * gst_vaapi_display_get_decode_profiles:
1366 * @display: a #GstVaapiDisplay
1368 * Gets the supported profiles for decoding. The caller owns an extra
1369 * reference to the resulting array of #GstVaapiProfile elements, so
1370 * it shall be released with g_array_unref() after usage.
1372 * Return value: a newly allocated #GArray, or %NULL or error or if
1373 * decoding is not supported at all
1376 gst_vaapi_display_get_decode_profiles (GstVaapiDisplay * display)
1378 g_return_val_if_fail (display != NULL, NULL);
1380 if (!ensure_profiles (display))
1382 return get_profiles (GST_VAAPI_DISPLAY_GET_PRIVATE (display)->decoders);
1386 * gst_vaapi_display_has_decoder:
1387 * @display: a #GstVaapiDisplay
1388 * @profile: a #VAProfile
1389 * @entrypoint: a #GstVaaiEntrypoint
1391 * Returns whether VA @display supports @profile for decoding at the
1392 * specified @entrypoint.
1394 * Return value: %TRUE if VA @display supports @profile for decoding.
1397 gst_vaapi_display_has_decoder (GstVaapiDisplay * display,
1398 GstVaapiProfile profile, GstVaapiEntrypoint entrypoint)
1400 g_return_val_if_fail (display != NULL, FALSE);
1402 if (!ensure_profiles (display))
1404 return find_config (GST_VAAPI_DISPLAY_GET_PRIVATE (display)->decoders,
1405 profile, entrypoint);
1409 * gst_vaapi_display_get_encode_profiles:
1410 * @display: a #GstVaapiDisplay
1412 * Gets the supported profiles for encoding. The caller owns an extra
1413 * reference to the resulting array of #GstVaapiProfile elements, so
1414 * it shall be released with g_array_unref() after usage.
1416 * Return value: a newly allocated #GArray, or %NULL or error or if
1417 * encoding is not supported at all
1420 gst_vaapi_display_get_encode_profiles (GstVaapiDisplay * display)
1422 g_return_val_if_fail (display != NULL, NULL);
1424 if (!ensure_profiles (display))
1426 return get_profiles (GST_VAAPI_DISPLAY_GET_PRIVATE (display)->encoders);
1430 * gst_vaapi_display_has_encoder:
1431 * @display: a #GstVaapiDisplay
1432 * @profile: a #VAProfile
1433 * @entrypoint: a #GstVaapiEntrypoint
1435 * Returns whether VA @display supports @profile for encoding at the
1436 * specified @entrypoint.
1438 * Return value: %TRUE if VA @display supports @profile for encoding.
1441 gst_vaapi_display_has_encoder (GstVaapiDisplay * display,
1442 GstVaapiProfile profile, GstVaapiEntrypoint entrypoint)
1444 g_return_val_if_fail (display != NULL, FALSE);
1446 if (!ensure_profiles (display))
1448 return find_config (GST_VAAPI_DISPLAY_GET_PRIVATE (display)->encoders,
1449 profile, entrypoint);
1453 * gst_vaapi_display_get_image_formats:
1454 * @display: a #GstVaapiDisplay
1456 * Gets the supported image formats for gst_vaapi_surface_get_image()
1457 * or gst_vaapi_surface_put_image().
1459 * Note that this method does not necessarily map image formats
1460 * returned by vaQueryImageFormats(). The set of capabilities can be
1461 * stripped down, if gstreamer-vaapi does not support the format, or
1462 * expanded to cover compatible formats not exposed by the underlying
1463 * driver. e.g. I420 can be supported even if the driver only exposes
1466 * Note: the caller owns an extra reference to the resulting array of
1467 * #GstVideoFormat elements, so it shall be released with
1468 * g_array_unref() after usage.
1470 * Return value: a newly allocated #GArray, or %NULL on error or if
1474 gst_vaapi_display_get_image_formats (GstVaapiDisplay * display)
1476 g_return_val_if_fail (display != NULL, NULL);
1478 if (!ensure_image_formats (display))
1480 return get_formats (GST_VAAPI_DISPLAY_GET_PRIVATE (display)->image_formats);
1484 * gst_vaapi_display_has_image_format:
1485 * @display: a #GstVaapiDisplay
1486 * @format: a #GstVideoFormat
1488 * Returns whether VA @display supports @format image format.
1490 * Return value: %TRUE if VA @display supports @format image format
1493 gst_vaapi_display_has_image_format (GstVaapiDisplay * display,
1494 GstVideoFormat format)
1496 GstVaapiDisplayPrivate *priv;
1498 g_return_val_if_fail (display != NULL, FALSE);
1499 g_return_val_if_fail (format, FALSE);
1501 priv = GST_VAAPI_DISPLAY_GET_PRIVATE (display);
1503 if (!ensure_image_formats (display))
1505 if (find_format (priv->image_formats, format))
1508 /* XXX: try subpicture formats since some drivers could report a
1509 * set of VA image formats that is not a superset of the set of VA
1510 * subpicture formats
1512 if (!ensure_subpicture_formats (display))
1514 return find_format (priv->subpicture_formats, format);
1518 * gst_vaapi_display_get_subpicture_formats:
1519 * @display: a #GstVaapiDisplay
1521 * Gets the supported subpicture formats.
1523 * Note that this method does not necessarily map subpicture formats
1524 * returned by vaQuerySubpictureFormats(). The set of capabilities can
1525 * be stripped down if gstreamer-vaapi does not support the
1526 * format. e.g. this is the case for paletted formats like IA44.
1528 * Note: the caller owns an extra reference to the resulting array of
1529 * #GstVideoFormat elements, so it shall be released with
1530 * g_array_unref() after usage.
1532 * Return value: a newly allocated #GArray, or %NULL on error of if
1536 gst_vaapi_display_get_subpicture_formats (GstVaapiDisplay * display)
1538 g_return_val_if_fail (display != NULL, NULL);
1540 if (!ensure_subpicture_formats (display))
1543 get_formats (GST_VAAPI_DISPLAY_GET_PRIVATE (display)->subpicture_formats);
1547 * gst_vaapi_display_has_subpicture_format:
1548 * @display: a #GstVaapiDisplay
1549 * @format: a #GstVideoFormat
1550 * @flags_ptr: pointer to #GstVaapiSubpictureFlags, or zero
1552 * Returns whether VA @display supports @format subpicture format with
1553 * the supplied @flags.
1555 * Return value: %TRUE if VA @display supports @format subpicture format
1558 gst_vaapi_display_has_subpicture_format (GstVaapiDisplay * display,
1559 GstVideoFormat format, guint * flags_ptr)
1561 GstVaapiDisplayPrivate *priv;
1562 const GstVaapiFormatInfo *fip;
1564 g_return_val_if_fail (display != NULL, FALSE);
1565 g_return_val_if_fail (format, FALSE);
1567 priv = GST_VAAPI_DISPLAY_GET_PRIVATE (display);
1569 if (!ensure_subpicture_formats (display))
1572 fip = find_format_info (priv->subpicture_formats, format);
1577 *flags_ptr = fip->flags;
1582 * gst_vaapi_display_has_property:
1583 * @display: a #GstVaapiDisplay
1584 * @name: the property name to check
1586 * Returns whether VA @display supports the requested property. The
1587 * check is performed against the property @name. So, the client
1588 * application may perform this check only once and cache this
1591 * Return value: %TRUE if VA @display supports property @name
1594 gst_vaapi_display_has_property (GstVaapiDisplay * display, const gchar * name)
1596 g_return_val_if_fail (display != NULL, FALSE);
1597 g_return_val_if_fail (name, FALSE);
1599 if (!ensure_properties (display))
1601 return find_property (GST_VAAPI_DISPLAY_GET_PRIVATE (display)->properties,
1606 gst_vaapi_display_get_property (GstVaapiDisplay * display, const gchar * name,
1609 const GstVaapiProperty *prop;
1611 g_return_val_if_fail (display != NULL, FALSE);
1612 g_return_val_if_fail (name != NULL, FALSE);
1613 g_return_val_if_fail (out_value != NULL, FALSE);
1615 if (!ensure_properties (display))
1619 find_property (GST_VAAPI_DISPLAY_GET_PRIVATE (display)->properties, name);
1623 switch (prop->attribute.type) {
1624 case VADisplayAttribRenderMode:{
1625 GstVaapiRenderMode mode;
1626 if (!gst_vaapi_display_get_render_mode (display, &mode))
1628 g_value_init (out_value, GST_VAAPI_TYPE_RENDER_MODE);
1629 g_value_set_enum (out_value, mode);
1632 case VADisplayAttribRotation:{
1633 GstVaapiRotation rotation;
1634 rotation = gst_vaapi_display_get_rotation (display);
1635 g_value_init (out_value, GST_VAAPI_TYPE_ROTATION);
1636 g_value_set_enum (out_value, rotation);
1639 case VADisplayAttribHue:
1640 case VADisplayAttribSaturation:
1641 case VADisplayAttribBrightness:
1642 case VADisplayAttribContrast:{
1644 if (!get_color_balance (display, find_property_id (name), &value))
1646 g_value_init (out_value, G_TYPE_FLOAT);
1647 g_value_set_float (out_value, value);
1651 GST_WARNING ("unsupported property '%s'", name);
1658 gst_vaapi_display_set_property (GstVaapiDisplay * display, const gchar * name,
1659 const GValue * value)
1661 const GstVaapiProperty *prop;
1663 g_return_val_if_fail (display != NULL, FALSE);
1664 g_return_val_if_fail (name != NULL, FALSE);
1665 g_return_val_if_fail (value != NULL, FALSE);
1667 if (!ensure_properties (display))
1671 find_property (GST_VAAPI_DISPLAY_GET_PRIVATE (display)->properties, name);
1675 switch (prop->attribute.type) {
1676 case VADisplayAttribRenderMode:{
1677 GstVaapiRenderMode mode;
1678 if (!G_VALUE_HOLDS (value, GST_VAAPI_TYPE_RENDER_MODE))
1680 mode = g_value_get_enum (value);
1681 return gst_vaapi_display_set_render_mode (display, mode);
1683 case VADisplayAttribRotation:{
1684 GstVaapiRotation rotation;
1685 if (!G_VALUE_HOLDS (value, GST_VAAPI_TYPE_ROTATION))
1687 rotation = g_value_get_enum (value);
1688 return gst_vaapi_display_set_rotation (display, rotation);
1690 case VADisplayAttribHue:
1691 case VADisplayAttribSaturation:
1692 case VADisplayAttribBrightness:
1693 case VADisplayAttribContrast:{
1695 if (!G_VALUE_HOLDS (value, G_TYPE_FLOAT))
1697 v = g_value_get_float (value);
1698 return set_color_balance (display, find_property_id (name), v);
1704 GST_WARNING ("unsupported property '%s'", name);
1709 get_attribute (GstVaapiDisplay * display, VADisplayAttribType type,
1712 GstVaapiDisplayPrivate *const priv = GST_VAAPI_DISPLAY_GET_PRIVATE (display);
1713 VADisplayAttribute attr = { 0, };
1717 attr.flags = VA_DISPLAY_ATTRIB_GETTABLE;
1718 status = vaGetDisplayAttributes (priv->display, &attr, 1);
1719 if (!vaapi_check_status (status, "vaGetDisplayAttributes()"))
1721 *value = attr.value;
1726 set_attribute (GstVaapiDisplay * display, VADisplayAttribType type, gint value)
1728 GstVaapiDisplayPrivate *const priv = GST_VAAPI_DISPLAY_GET_PRIVATE (display);
1729 VADisplayAttribute attr = { 0, };
1734 attr.flags = VA_DISPLAY_ATTRIB_SETTABLE;
1735 status = vaSetDisplayAttributes (priv->display, &attr, 1);
1736 if (!vaapi_check_status (status, "vaSetDisplayAttributes()"))
1742 get_render_mode_VADisplayAttribRenderMode (GstVaapiDisplay * display,
1743 GstVaapiRenderMode * pmode)
1745 gint modes, devices;
1747 if (!get_attribute (display, VADisplayAttribRenderDevice, &devices))
1751 if (!get_attribute (display, VADisplayAttribRenderMode, &modes))
1754 /* Favor "overlay" mode since it is the most restrictive one */
1755 if (modes & (VA_RENDER_MODE_LOCAL_OVERLAY | VA_RENDER_MODE_EXTERNAL_OVERLAY))
1756 *pmode = GST_VAAPI_RENDER_MODE_OVERLAY;
1758 *pmode = GST_VAAPI_RENDER_MODE_TEXTURE;
1763 get_render_mode_VADisplayAttribDirectSurface (GstVaapiDisplay * display,
1764 GstVaapiRenderMode * pmode)
1766 #if VA_CHECK_VERSION(0,34,0)
1767 /* VADisplayAttribDirectsurface was removed in VA-API >= 0.34.0 */
1770 gint direct_surface;
1772 if (!get_attribute (display, VADisplayAttribDirectSurface, &direct_surface))
1775 *pmode = GST_VAAPI_RENDER_MODE_OVERLAY;
1777 *pmode = GST_VAAPI_RENDER_MODE_TEXTURE;
1783 get_render_mode_default (GstVaapiDisplay * display, GstVaapiRenderMode * pmode)
1785 GstVaapiDisplayPrivate *const priv = GST_VAAPI_DISPLAY_GET_PRIVATE (display);
1787 switch (priv->display_type) {
1789 case GST_VAAPI_DISPLAY_TYPE_WAYLAND:
1790 /* wl_buffer mapped from VA surface through vaGetSurfaceBufferWl() */
1791 *pmode = GST_VAAPI_RENDER_MODE_OVERLAY;
1795 case GST_VAAPI_DISPLAY_TYPE_DRM:
1796 /* vaGetSurfaceBufferDRM() returns the underlying DRM buffer handle */
1797 *pmode = GST_VAAPI_RENDER_MODE_OVERLAY;
1801 /* This includes VA/X11 and VA/GLX modes */
1802 *pmode = DEFAULT_RENDER_MODE;
1809 * gst_vaapi_display_get_render_mode:
1810 * @display: a #GstVaapiDisplay
1811 * @pmode: return location for the VA @display rendering mode
1813 * Returns the current VA @display rendering mode.
1815 * Return value: %TRUE if VA @display rendering mode could be determined
1818 gst_vaapi_display_get_render_mode (GstVaapiDisplay * display,
1819 GstVaapiRenderMode * pmode)
1821 g_return_val_if_fail (display != NULL, FALSE);
1823 /* Try with render-mode attribute */
1824 if (get_render_mode_VADisplayAttribRenderMode (display, pmode))
1827 /* Try with direct-surface attribute */
1828 if (get_render_mode_VADisplayAttribDirectSurface (display, pmode))
1831 /* Default: determine from the display type */
1832 return get_render_mode_default (display, pmode);
1836 * gst_vaapi_display_set_render_mode:
1837 * @display: a #GstVaapiDisplay
1838 * @mode: the #GstVaapiRenderMode to set
1840 * Sets the VA @display rendering mode to the supplied @mode. This
1841 * function returns %FALSE if the rendering mode could not be set,
1842 * e.g. run-time switching rendering mode is not supported.
1844 * Return value: %TRUE if VA @display rendering @mode could be changed
1845 * to the requested value
1848 gst_vaapi_display_set_render_mode (GstVaapiDisplay * display,
1849 GstVaapiRenderMode mode)
1851 gint modes, devices;
1853 g_return_val_if_fail (display != NULL, FALSE);
1855 if (!get_attribute (display, VADisplayAttribRenderDevice, &devices))
1860 case GST_VAAPI_RENDER_MODE_OVERLAY:
1861 if (devices & VA_RENDER_DEVICE_LOCAL)
1862 modes |= VA_RENDER_MODE_LOCAL_OVERLAY;
1863 if (devices & VA_RENDER_DEVICE_EXTERNAL)
1864 modes |= VA_RENDER_MODE_EXTERNAL_OVERLAY;
1866 case GST_VAAPI_RENDER_MODE_TEXTURE:
1867 if (devices & VA_RENDER_DEVICE_LOCAL)
1868 modes |= VA_RENDER_MODE_LOCAL_GPU;
1869 if (devices & VA_RENDER_DEVICE_EXTERNAL)
1870 modes |= VA_RENDER_MODE_EXTERNAL_GPU;
1875 if (!set_attribute (display, VADisplayAttribRenderMode, modes))
1881 * gst_vaapi_display_get_rotation:
1882 * @display: a #GstVaapiDisplay
1884 * Returns the current VA @display rotation angle. If the VA driver
1885 * does not support "rotation" display attribute, then the display is
1886 * assumed to be un-rotated.
1888 * Return value: the current #GstVaapiRotation value
1891 gst_vaapi_display_get_rotation (GstVaapiDisplay * display)
1895 g_return_val_if_fail (display != NULL, DEFAULT_ROTATION);
1897 if (!get_attribute (display, VADisplayAttribRotation, &value))
1898 value = VA_ROTATION_NONE;
1899 return to_GstVaapiRotation (value);
1903 * gst_vaapi_display_set_rotation:
1904 * @display: a #GstVaapiDisplay
1905 * @rotation: the #GstVaapiRotation value to set
1907 * Sets the VA @display rotation angle to the supplied @rotation
1908 * value. This function returns %FALSE if the rotation angle could not
1909 * be set, e.g. the VA driver does not allow to change the display
1912 * Return value: %TRUE if VA @display rotation angle could be changed
1913 * to the requested value
1916 gst_vaapi_display_set_rotation (GstVaapiDisplay * display,
1917 GstVaapiRotation rotation)
1921 g_return_val_if_fail (display != NULL, FALSE);
1923 value = from_GstVaapiRotation (rotation);
1924 if (!set_attribute (display, VADisplayAttribRotation, value))
1929 /* Get color balance attributes */
1931 get_color_balance (GstVaapiDisplay * display, guint prop_id, gfloat * v)
1933 GParamSpecFloat *const pspec = G_PARAM_SPEC_FLOAT (g_properties[prop_id]);
1934 const GstVaapiProperty *prop;
1935 const VADisplayAttribute *attr;
1939 if (!ensure_properties (display))
1945 prop = find_property_by_pspec (display, &pspec->parent_instance);
1948 attr = &prop->attribute;
1950 if (!get_attribute (display, attr->type, &value))
1953 /* Scale wrt. the medium ("default") value */
1954 out_value = pspec->default_value;
1955 if (value > attr->value)
1956 out_value += ((gfloat) (value - attr->value) /
1957 (attr->max_value - attr->value) *
1958 (pspec->maximum - pspec->default_value));
1959 else if (value < attr->value)
1960 out_value -= ((gfloat) (attr->value - value) /
1961 (attr->value - attr->min_value) *
1962 (pspec->default_value - pspec->minimum));
1967 /* Set color balance attribute */
1969 set_color_balance (GstVaapiDisplay * display, guint prop_id, gfloat v)
1971 GParamSpecFloat *const pspec = G_PARAM_SPEC_FLOAT (g_properties[prop_id]);
1972 const GstVaapiProperty *prop;
1973 const VADisplayAttribute *attr;
1976 if (!ensure_properties (display))
1982 prop = find_property_by_pspec (display, &pspec->parent_instance);
1985 attr = &prop->attribute;
1987 /* Scale wrt. the medium ("default") value */
1988 value = attr->value;
1989 if (v > pspec->default_value)
1990 value += ((v - pspec->default_value) /
1991 (pspec->maximum - pspec->default_value) *
1992 (attr->max_value - attr->value));
1993 else if (v < pspec->default_value)
1994 value -= ((pspec->default_value - v) /
1995 (pspec->default_value - pspec->minimum) *
1996 (attr->value - attr->min_value));
1997 if (!set_attribute (display, attr->type, value))
2002 /* Ensures the VA driver vendor string was copied */
2004 ensure_vendor_string (GstVaapiDisplay * display)
2006 GstVaapiDisplayPrivate *const priv = GST_VAAPI_DISPLAY_GET_PRIVATE (display);
2007 const gchar *vendor_string;
2009 GST_VAAPI_DISPLAY_LOCK (display);
2010 if (!priv->vendor_string) {
2011 vendor_string = vaQueryVendorString (priv->display);
2013 priv->vendor_string = g_strdup (vendor_string);
2015 GST_VAAPI_DISPLAY_UNLOCK (display);
2016 return priv->vendor_string != NULL;
2020 * gst_vaapi_display_get_vendor_string:
2021 * @display: a #GstVaapiDisplay
2023 * Returns the VA driver vendor string attached to the supplied VA @display.
2024 * The @display owns the vendor string, do *not* de-allocate it.
2026 * This function is thread safe.
2028 * Return value: the current #GstVaapiRotation value
2031 gst_vaapi_display_get_vendor_string (GstVaapiDisplay * display)
2033 g_return_val_if_fail (display != NULL, NULL);
2035 if (!ensure_vendor_string (display))
2037 return GST_VAAPI_DISPLAY_GET_PRIVATE (display)->vendor_string;
2041 * gst_vaapi_display_has_opengl:
2042 * @display: a #GstVaapiDisplay
2044 * Returns wether the @display that was created does support OpenGL
2045 * context to be attached.
2047 * This function is thread safe.
2049 * Return value: %TRUE if the @display supports OpenGL context, %FALSE
2053 gst_vaapi_display_has_opengl (GstVaapiDisplay * display)
2055 GstVaapiDisplayClass *klass;
2057 g_return_val_if_fail (display != NULL, FALSE);
2059 klass = GST_VAAPI_DISPLAY_GET_CLASS (display);
2060 return (klass->display_type == GST_VAAPI_DISPLAY_TYPE_GLX ||
2061 klass->display_type == GST_VAAPI_DISPLAY_TYPE_EGL);
2065 * gst_vaapi_display_reset_texture_map:
2066 * @display: a #GstVaapiDisplay
2068 * Reset the internal #GstVaapiTextureMap if available.
2070 * This function is thread safe.
2073 gst_vaapi_display_reset_texture_map (GstVaapiDisplay * display)
2075 GstVaapiDisplayClass *klass;
2076 GstVaapiTextureMap *map;
2078 g_return_if_fail (display != NULL);
2080 if (!gst_vaapi_display_has_opengl (display))
2082 klass = GST_VAAPI_DISPLAY_GET_CLASS (display);
2083 if (!klass->get_texture_map)
2085 if ((map = klass->get_texture_map (display)))
2086 gst_vaapi_texture_map_reset (map);