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 data)
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 .display_type = priv->display_type,
866 case GST_VAAPI_DISPLAY_INIT_FROM_VA_DISPLAY:{
867 GstVaapiDisplayInfo *p_info = data;
869 info.va_display = p_info->va_display;
870 info.display_type = p_info->display_type;
871 priv->display = p_info->va_display;
872 priv->use_foreign_display = TRUE;
874 if (!klass->bind_display)
877 data = p_info->native_display;
880 case GST_VAAPI_DISPLAY_INIT_FROM_DISPLAY_NAME:
881 if (klass->open_display && !klass->open_display (display, data))
884 case GST_VAAPI_DISPLAY_INIT_FROM_NATIVE_DISPLAY:
886 if (klass->bind_display && !klass->bind_display (display, data))
890 if (!klass->get_display || !klass->get_display (display, &info))
892 priv->display = info.va_display;
893 priv->display_type = info.display_type;
894 priv->native_display = info.native_display;
896 klass->get_size (display, &priv->width, &priv->height);
897 if (klass->get_size_mm)
898 klass->get_size_mm (display, &priv->width_mm, &priv->height_mm);
899 gst_vaapi_display_calculate_pixel_aspect_ratio (display);
906 if (!vaapi_initialize (priv->display))
910 GST_INFO_OBJECT (display, "new display addr=%p", display);
911 g_free (priv->display_name);
912 priv->display_name = g_strdup (info.display_name);
917 gst_vaapi_display_create (GstVaapiDisplay * display,
918 GstVaapiDisplayInitType init_type, gpointer init_value)
920 return gst_vaapi_display_create_unlocked (display, init_type, init_value);
924 gst_vaapi_display_lock_default (GstVaapiDisplay * display)
926 GstVaapiDisplayPrivate *priv = GST_VAAPI_DISPLAY_GET_PRIVATE (display);
929 priv = GST_VAAPI_DISPLAY_GET_PRIVATE (priv->parent);
930 g_rec_mutex_lock (&priv->mutex);
934 gst_vaapi_display_unlock_default (GstVaapiDisplay * display)
936 GstVaapiDisplayPrivate *priv = GST_VAAPI_DISPLAY_GET_PRIVATE (display);
939 priv = GST_VAAPI_DISPLAY_GET_PRIVATE (priv->parent);
940 g_rec_mutex_unlock (&priv->mutex);
944 gst_vaapi_display_init (GstVaapiDisplay * display)
946 GstVaapiDisplayPrivate *const priv =
947 gst_vaapi_display_get_instance_private (display);
949 display->priv = priv;
950 priv->display_type = GST_VAAPI_DISPLAY_TYPE_ANY;
954 g_rec_mutex_init (&priv->mutex);
958 gst_vaapi_display_finalize (GObject * object)
960 GstVaapiDisplay *const display = GST_VAAPI_DISPLAY (object);
961 GstVaapiDisplayPrivate *const priv = GST_VAAPI_DISPLAY_GET_PRIVATE (display);
963 gst_vaapi_display_destroy (display);
964 g_rec_mutex_clear (&priv->mutex);
966 G_OBJECT_CLASS (gst_vaapi_display_parent_class)->finalize (object);
970 gst_vaapi_display_class_init (GstVaapiDisplayClass * klass)
972 GObjectClass *const object_class = G_OBJECT_CLASS (klass);
974 libgstvaapi_init_once ();
976 object_class->finalize = gst_vaapi_display_finalize;
977 klass->lock = gst_vaapi_display_lock_default;
978 klass->unlock = gst_vaapi_display_unlock_default;
982 gst_vaapi_display_properties_init (void)
985 * GstVaapiDisplay:render-mode:
987 * The VA display rendering mode, expressed as a #GstVaapiRenderMode.
989 g_properties[PROP_RENDER_MODE] =
990 g_param_spec_enum (GST_VAAPI_DISPLAY_PROP_RENDER_MODE,
992 "The display rendering mode",
993 GST_VAAPI_TYPE_RENDER_MODE, DEFAULT_RENDER_MODE, G_PARAM_READWRITE);
996 * GstVaapiDisplay:rotation:
998 * The VA display rotation mode, expressed as a #GstVaapiRotation.
1000 g_properties[PROP_ROTATION] =
1001 g_param_spec_enum (GST_VAAPI_DISPLAY_PROP_ROTATION,
1003 "The display rotation mode",
1004 GST_VAAPI_TYPE_ROTATION, DEFAULT_ROTATION, G_PARAM_READWRITE);
1007 * GstVaapiDisplay:hue:
1009 * The VA display hue, expressed as a float value. Range is -180.0
1010 * to 180.0. Default value is 0.0 and represents no modification.
1012 g_properties[PROP_HUE] =
1013 g_param_spec_float (GST_VAAPI_DISPLAY_PROP_HUE,
1014 "hue", "The display hue value", -180.0, 180.0, 0.0, G_PARAM_READWRITE);
1017 * GstVaapiDisplay:saturation:
1019 * The VA display saturation, expressed as a float value. Range is
1020 * 0.0 to 2.0. Default value is 1.0 and represents no modification.
1022 g_properties[PROP_SATURATION] =
1023 g_param_spec_float (GST_VAAPI_DISPLAY_PROP_SATURATION,
1025 "The display saturation value", 0.0, 2.0, 1.0, G_PARAM_READWRITE);
1028 * GstVaapiDisplay:brightness:
1030 * The VA display brightness, expressed as a float value. Range is
1031 * -1.0 to 1.0. Default value is 0.0 and represents no modification.
1033 g_properties[PROP_BRIGHTNESS] =
1034 g_param_spec_float (GST_VAAPI_DISPLAY_PROP_BRIGHTNESS,
1036 "The display brightness value", -1.0, 1.0, 0.0, G_PARAM_READWRITE);
1039 * GstVaapiDisplay:contrast:
1041 * The VA display contrast, expressed as a float value. Range is 0.0
1042 * to 2.0. Default value is 1.0 and represents no modification.
1044 g_properties[PROP_CONTRAST] =
1045 g_param_spec_float (GST_VAAPI_DISPLAY_PROP_CONTRAST,
1047 "The display contrast value", 0.0, 2.0, 1.0, G_PARAM_READWRITE);
1051 gst_vaapi_display_new (GstVaapiDisplay * display,
1052 GstVaapiDisplayInitType init_type, gpointer init_value)
1054 g_return_val_if_fail (display != NULL, NULL);
1056 if (!gst_vaapi_display_create (display, init_type, init_value))
1063 gst_vaapi_display_unref_internal (display);
1069 * gst_vaapi_display_new_with_display:
1070 * @va_display: a #VADisplay
1072 * Creates a new #GstVaapiDisplay, using @va_display as the VA
1075 * Return value: the newly created #GstVaapiDisplay object
1078 gst_vaapi_display_new_with_display (VADisplay va_display)
1080 GstVaapiDisplayInfo info = {
1081 .va_display = va_display,
1082 .display_type = GST_VAAPI_DISPLAY_TYPE_ANY,
1085 return gst_vaapi_display_new (g_object_new (GST_TYPE_VAAPI_DISPLAY, NULL),
1086 GST_VAAPI_DISPLAY_INIT_FROM_VA_DISPLAY, &info);
1090 * gst_vaapi_display_ref:
1091 * @display: a #GstVaapiDisplay
1093 * Atomically increases the reference count of the given @display by one.
1095 * Returns: The same @display argument
1098 gst_vaapi_display_ref (GstVaapiDisplay * display)
1100 return gst_vaapi_display_ref_internal (display);
1104 * gst_vaapi_display_unref:
1105 * @display: a #GstVaapiDisplay
1107 * Atomically decreases the reference count of the @display by one. If
1108 * the reference count reaches zero, the display will be free'd.
1111 gst_vaapi_display_unref (GstVaapiDisplay * display)
1113 gst_vaapi_display_unref_internal (display);
1117 * gst_vaapi_display_replace:
1118 * @old_display_ptr: a pointer to a #GstVaapiDisplay
1119 * @new_display: a #GstVaapiDisplay
1121 * Atomically replaces the display display held in @old_display_ptr
1122 * with @new_display. This means that @old_display_ptr shall reference
1123 * a valid display. However, @new_display can be NULL.
1126 gst_vaapi_display_replace (GstVaapiDisplay ** old_display_ptr,
1127 GstVaapiDisplay * new_display)
1129 gst_vaapi_display_replace_internal (old_display_ptr, new_display);
1133 * gst_vaapi_display_lock:
1134 * @display: a #GstVaapiDisplay
1136 * Locks @display. If @display is already locked by another thread,
1137 * the current thread will block until @display is unlocked by the
1141 gst_vaapi_display_lock (GstVaapiDisplay * display)
1143 GstVaapiDisplayClass *klass;
1145 g_return_if_fail (display != NULL);
1147 klass = GST_VAAPI_DISPLAY_GET_CLASS (display);
1149 klass->lock (display);
1153 * gst_vaapi_display_unlock:
1154 * @display: a #GstVaapiDisplay
1156 * Unlocks @display. If another thread is blocked in a
1157 * gst_vaapi_display_lock() call for @display, it will be woken and
1158 * can lock @display itself.
1161 gst_vaapi_display_unlock (GstVaapiDisplay * display)
1163 GstVaapiDisplayClass *klass;
1165 g_return_if_fail (display != NULL);
1167 klass = GST_VAAPI_DISPLAY_GET_CLASS (display);
1169 klass->unlock (display);
1173 * gst_vaapi_display_sync:
1174 * @display: a #GstVaapiDisplay
1176 * Flushes any requests queued for the windowing system and waits until
1177 * all requests have been handled. This is often used for making sure
1178 * that the display is synchronized with the current state of the program.
1180 * This is most useful for X11. On windowing systems where requests are
1181 * handled synchronously, this function will do nothing.
1184 gst_vaapi_display_sync (GstVaapiDisplay * display)
1186 GstVaapiDisplayClass *klass;
1188 g_return_if_fail (display != NULL);
1190 klass = GST_VAAPI_DISPLAY_GET_CLASS (display);
1192 klass->sync (display);
1193 else if (klass->flush)
1194 klass->flush (display);
1198 * gst_vaapi_display_flush:
1199 * @display: a #GstVaapiDisplay
1201 * Flushes any requests queued for the windowing system.
1203 * This is most useful for X11. On windowing systems where requests
1204 * are handled synchronously, this function will do nothing.
1207 gst_vaapi_display_flush (GstVaapiDisplay * display)
1209 GstVaapiDisplayClass *klass;
1211 g_return_if_fail (display != NULL);
1213 klass = GST_VAAPI_DISPLAY_GET_CLASS (display);
1215 klass->flush (display);
1219 * gst_vaapi_display_get_class_type:
1220 * @display: a #GstVaapiDisplay
1222 * Returns the #GstVaapiDisplayType of @display. This is the type of
1223 * the object, thus the associated class, not the type of the VA
1226 * Return value: the #GstVaapiDisplayType
1229 gst_vaapi_display_get_class_type (GstVaapiDisplay * display)
1231 g_return_val_if_fail (display != NULL, GST_VAAPI_DISPLAY_TYPE_ANY);
1233 return GST_VAAPI_DISPLAY_GET_CLASS_TYPE (display);
1237 * gst_vaapi_display_get_display_type:
1238 * @display: a #GstVaapiDisplay
1240 * Returns the #GstVaapiDisplayType of the VA display bound to
1241 * @display. This is not the type of the @display object.
1243 * Return value: the #GstVaapiDisplayType
1246 gst_vaapi_display_get_display_type (GstVaapiDisplay * display)
1248 g_return_val_if_fail (display != NULL, GST_VAAPI_DISPLAY_TYPE_ANY);
1250 return GST_VAAPI_DISPLAY_VADISPLAY_TYPE (display);
1254 * gst_vaapi_display_get_display_type:
1255 * @display: a #GstVaapiDisplay
1257 * Returns the @display name.
1259 * Return value: the display name
1262 gst_vaapi_display_get_display_name (GstVaapiDisplay * display)
1264 g_return_val_if_fail (display != NULL, NULL);
1266 return GST_VAAPI_DISPLAY_GET_PRIVATE (display)->display_name;
1270 * gst_vaapi_display_get_display:
1271 * @display: a #GstVaapiDisplay
1273 * Returns the #VADisplay bound to @display.
1275 * Return value: the #VADisplay
1278 gst_vaapi_display_get_display (GstVaapiDisplay * display)
1280 g_return_val_if_fail (display != NULL, NULL);
1282 return GST_VAAPI_DISPLAY_GET_PRIVATE (display)->display;
1286 * gst_vaapi_display_get_width:
1287 * @display: a #GstVaapiDisplay
1289 * Retrieves the width of a #GstVaapiDisplay.
1291 * Return value: the width of the @display, in pixels
1294 gst_vaapi_display_get_width (GstVaapiDisplay * display)
1296 g_return_val_if_fail (display != NULL, 0);
1298 return GST_VAAPI_DISPLAY_GET_PRIVATE (display)->width;
1302 * gst_vaapi_display_get_height:
1303 * @display: a #GstVaapiDisplay
1305 * Retrieves the height of a #GstVaapiDisplay
1307 * Return value: the height of the @display, in pixels
1310 gst_vaapi_display_get_height (GstVaapiDisplay * display)
1312 g_return_val_if_fail (display != NULL, 0);
1314 return GST_VAAPI_DISPLAY_GET_PRIVATE (display)->height;
1318 * gst_vaapi_display_get_size:
1319 * @display: a #GstVaapiDisplay
1320 * @pwidth: return location for the width, or %NULL
1321 * @pheight: return location for the height, or %NULL
1323 * Retrieves the dimensions of a #GstVaapiDisplay.
1326 gst_vaapi_display_get_size (GstVaapiDisplay * display, guint * pwidth,
1329 g_return_if_fail (GST_VAAPI_DISPLAY (display));
1332 *pwidth = GST_VAAPI_DISPLAY_GET_PRIVATE (display)->width;
1335 *pheight = GST_VAAPI_DISPLAY_GET_PRIVATE (display)->height;
1339 * gst_vaapi_display_get_pixel_aspect_ratio:
1340 * @display: a #GstVaapiDisplay
1341 * @par_n: return location for the numerator of pixel aspect ratio, or %NULL
1342 * @par_d: return location for the denominator of pixel aspect ratio, or %NULL
1344 * Retrieves the pixel aspect ratio of a #GstVaapiDisplay.
1347 gst_vaapi_display_get_pixel_aspect_ratio (GstVaapiDisplay * display,
1348 guint * par_n, guint * par_d)
1350 g_return_if_fail (display != NULL);
1353 *par_n = GST_VAAPI_DISPLAY_GET_PRIVATE (display)->par_n;
1356 *par_d = GST_VAAPI_DISPLAY_GET_PRIVATE (display)->par_d;
1360 * gst_vaapi_display_has_video_processing:
1361 * @display: a #GstVaapiDisplay
1363 * Checks whether the underlying VA driver implementation supports
1364 * video processing (VPP) acceleration.
1366 * Returns: %TRUE if some VPP features are available
1369 gst_vaapi_display_has_video_processing (GstVaapiDisplay * display)
1371 g_return_val_if_fail (display != NULL, FALSE);
1373 if (!ensure_profiles (display))
1375 return GST_VAAPI_DISPLAY_GET_PRIVATE (display)->has_vpp;
1379 * gst_vaapi_display_get_decode_profiles:
1380 * @display: a #GstVaapiDisplay
1382 * Gets the supported profiles for decoding. The caller owns an extra
1383 * reference to the resulting array of #GstVaapiProfile elements, so
1384 * it shall be released with g_array_unref() after usage.
1386 * Return value: a newly allocated #GArray, or %NULL or error or if
1387 * decoding is not supported at all
1390 gst_vaapi_display_get_decode_profiles (GstVaapiDisplay * display)
1392 g_return_val_if_fail (display != NULL, NULL);
1394 if (!ensure_profiles (display))
1396 return get_profiles (GST_VAAPI_DISPLAY_GET_PRIVATE (display)->decoders);
1400 * gst_vaapi_display_has_decoder:
1401 * @display: a #GstVaapiDisplay
1402 * @profile: a #VAProfile
1403 * @entrypoint: a #GstVaaiEntrypoint
1405 * Returns whether VA @display supports @profile for decoding at the
1406 * specified @entrypoint.
1408 * Return value: %TRUE if VA @display supports @profile for decoding.
1411 gst_vaapi_display_has_decoder (GstVaapiDisplay * display,
1412 GstVaapiProfile profile, GstVaapiEntrypoint entrypoint)
1414 g_return_val_if_fail (display != NULL, FALSE);
1416 if (!ensure_profiles (display))
1418 return find_config (GST_VAAPI_DISPLAY_GET_PRIVATE (display)->decoders,
1419 profile, entrypoint);
1423 * gst_vaapi_display_get_encode_profiles:
1424 * @display: a #GstVaapiDisplay
1426 * Gets the supported profiles for encoding. The caller owns an extra
1427 * reference to the resulting array of #GstVaapiProfile elements, so
1428 * it shall be released with g_array_unref() after usage.
1430 * Return value: a newly allocated #GArray, or %NULL or error or if
1431 * encoding is not supported at all
1434 gst_vaapi_display_get_encode_profiles (GstVaapiDisplay * display)
1436 g_return_val_if_fail (display != NULL, NULL);
1438 if (!ensure_profiles (display))
1440 return get_profiles (GST_VAAPI_DISPLAY_GET_PRIVATE (display)->encoders);
1444 * gst_vaapi_display_has_encoder:
1445 * @display: a #GstVaapiDisplay
1446 * @profile: a #VAProfile
1447 * @entrypoint: a #GstVaapiEntrypoint
1449 * Returns whether VA @display supports @profile for encoding at the
1450 * specified @entrypoint.
1452 * Return value: %TRUE if VA @display supports @profile for encoding.
1455 gst_vaapi_display_has_encoder (GstVaapiDisplay * display,
1456 GstVaapiProfile profile, GstVaapiEntrypoint entrypoint)
1458 g_return_val_if_fail (display != NULL, FALSE);
1460 if (!ensure_profiles (display))
1462 return find_config (GST_VAAPI_DISPLAY_GET_PRIVATE (display)->encoders,
1463 profile, entrypoint);
1467 * gst_vaapi_display_get_image_formats:
1468 * @display: a #GstVaapiDisplay
1470 * Gets the supported image formats for gst_vaapi_surface_get_image()
1471 * or gst_vaapi_surface_put_image().
1473 * Note that this method does not necessarily map image formats
1474 * returned by vaQueryImageFormats(). The set of capabilities can be
1475 * stripped down, if gstreamer-vaapi does not support the format, or
1476 * expanded to cover compatible formats not exposed by the underlying
1477 * driver. e.g. I420 can be supported even if the driver only exposes
1480 * Note: the caller owns an extra reference to the resulting array of
1481 * #GstVideoFormat elements, so it shall be released with
1482 * g_array_unref() after usage.
1484 * Return value: a newly allocated #GArray, or %NULL on error or if
1488 gst_vaapi_display_get_image_formats (GstVaapiDisplay * display)
1490 g_return_val_if_fail (display != NULL, NULL);
1492 if (!ensure_image_formats (display))
1494 return get_formats (GST_VAAPI_DISPLAY_GET_PRIVATE (display)->image_formats);
1498 * gst_vaapi_display_has_image_format:
1499 * @display: a #GstVaapiDisplay
1500 * @format: a #GstVideoFormat
1502 * Returns whether VA @display supports @format image format.
1504 * Return value: %TRUE if VA @display supports @format image format
1507 gst_vaapi_display_has_image_format (GstVaapiDisplay * display,
1508 GstVideoFormat format)
1510 GstVaapiDisplayPrivate *priv;
1512 g_return_val_if_fail (display != NULL, FALSE);
1513 g_return_val_if_fail (format, FALSE);
1515 priv = GST_VAAPI_DISPLAY_GET_PRIVATE (display);
1517 if (!ensure_image_formats (display))
1519 if (find_format (priv->image_formats, format))
1522 /* XXX: try subpicture formats since some drivers could report a
1523 * set of VA image formats that is not a superset of the set of VA
1524 * subpicture formats
1526 if (!ensure_subpicture_formats (display))
1528 return find_format (priv->subpicture_formats, format);
1532 * gst_vaapi_display_get_subpicture_formats:
1533 * @display: a #GstVaapiDisplay
1535 * Gets the supported subpicture formats.
1537 * Note that this method does not necessarily map subpicture formats
1538 * returned by vaQuerySubpictureFormats(). The set of capabilities can
1539 * be stripped down if gstreamer-vaapi does not support the
1540 * format. e.g. this is the case for paletted formats like IA44.
1542 * Note: the caller owns an extra reference to the resulting array of
1543 * #GstVideoFormat elements, so it shall be released with
1544 * g_array_unref() after usage.
1546 * Return value: a newly allocated #GArray, or %NULL on error of if
1550 gst_vaapi_display_get_subpicture_formats (GstVaapiDisplay * display)
1552 g_return_val_if_fail (display != NULL, NULL);
1554 if (!ensure_subpicture_formats (display))
1557 get_formats (GST_VAAPI_DISPLAY_GET_PRIVATE (display)->subpicture_formats);
1561 * gst_vaapi_display_has_subpicture_format:
1562 * @display: a #GstVaapiDisplay
1563 * @format: a #GstVideoFormat
1564 * @flags_ptr: pointer to #GstVaapiSubpictureFlags, or zero
1566 * Returns whether VA @display supports @format subpicture format with
1567 * the supplied @flags.
1569 * Return value: %TRUE if VA @display supports @format subpicture format
1572 gst_vaapi_display_has_subpicture_format (GstVaapiDisplay * display,
1573 GstVideoFormat format, guint * flags_ptr)
1575 GstVaapiDisplayPrivate *priv;
1576 const GstVaapiFormatInfo *fip;
1578 g_return_val_if_fail (display != NULL, FALSE);
1579 g_return_val_if_fail (format, FALSE);
1581 priv = GST_VAAPI_DISPLAY_GET_PRIVATE (display);
1583 if (!ensure_subpicture_formats (display))
1586 fip = find_format_info (priv->subpicture_formats, format);
1591 *flags_ptr = fip->flags;
1596 * gst_vaapi_display_has_property:
1597 * @display: a #GstVaapiDisplay
1598 * @name: the property name to check
1600 * Returns whether VA @display supports the requested property. The
1601 * check is performed against the property @name. So, the client
1602 * application may perform this check only once and cache this
1605 * Return value: %TRUE if VA @display supports property @name
1608 gst_vaapi_display_has_property (GstVaapiDisplay * display, const gchar * name)
1610 g_return_val_if_fail (display != NULL, FALSE);
1611 g_return_val_if_fail (name, FALSE);
1613 if (!ensure_properties (display))
1615 return find_property (GST_VAAPI_DISPLAY_GET_PRIVATE (display)->properties,
1620 gst_vaapi_display_get_property (GstVaapiDisplay * display, const gchar * name,
1623 const GstVaapiProperty *prop;
1625 g_return_val_if_fail (display != NULL, FALSE);
1626 g_return_val_if_fail (name != NULL, FALSE);
1627 g_return_val_if_fail (out_value != NULL, FALSE);
1629 if (!ensure_properties (display))
1633 find_property (GST_VAAPI_DISPLAY_GET_PRIVATE (display)->properties, name);
1637 switch (prop->attribute.type) {
1638 case VADisplayAttribRenderMode:{
1639 GstVaapiRenderMode mode;
1640 if (!gst_vaapi_display_get_render_mode (display, &mode))
1642 g_value_init (out_value, GST_VAAPI_TYPE_RENDER_MODE);
1643 g_value_set_enum (out_value, mode);
1646 case VADisplayAttribRotation:{
1647 GstVaapiRotation rotation;
1648 rotation = gst_vaapi_display_get_rotation (display);
1649 g_value_init (out_value, GST_VAAPI_TYPE_ROTATION);
1650 g_value_set_enum (out_value, rotation);
1653 case VADisplayAttribHue:
1654 case VADisplayAttribSaturation:
1655 case VADisplayAttribBrightness:
1656 case VADisplayAttribContrast:{
1658 if (!get_color_balance (display, find_property_id (name), &value))
1660 g_value_init (out_value, G_TYPE_FLOAT);
1661 g_value_set_float (out_value, value);
1665 GST_WARNING ("unsupported property '%s'", name);
1672 gst_vaapi_display_set_property (GstVaapiDisplay * display, const gchar * name,
1673 const GValue * value)
1675 const GstVaapiProperty *prop;
1677 g_return_val_if_fail (display != NULL, FALSE);
1678 g_return_val_if_fail (name != NULL, FALSE);
1679 g_return_val_if_fail (value != NULL, FALSE);
1681 if (!ensure_properties (display))
1685 find_property (GST_VAAPI_DISPLAY_GET_PRIVATE (display)->properties, name);
1689 switch (prop->attribute.type) {
1690 case VADisplayAttribRenderMode:{
1691 GstVaapiRenderMode mode;
1692 if (!G_VALUE_HOLDS (value, GST_VAAPI_TYPE_RENDER_MODE))
1694 mode = g_value_get_enum (value);
1695 return gst_vaapi_display_set_render_mode (display, mode);
1697 case VADisplayAttribRotation:{
1698 GstVaapiRotation rotation;
1699 if (!G_VALUE_HOLDS (value, GST_VAAPI_TYPE_ROTATION))
1701 rotation = g_value_get_enum (value);
1702 return gst_vaapi_display_set_rotation (display, rotation);
1704 case VADisplayAttribHue:
1705 case VADisplayAttribSaturation:
1706 case VADisplayAttribBrightness:
1707 case VADisplayAttribContrast:{
1709 if (!G_VALUE_HOLDS (value, G_TYPE_FLOAT))
1711 v = g_value_get_float (value);
1712 return set_color_balance (display, find_property_id (name), v);
1718 GST_WARNING ("unsupported property '%s'", name);
1723 get_attribute (GstVaapiDisplay * display, VADisplayAttribType type,
1726 GstVaapiDisplayPrivate *const priv = GST_VAAPI_DISPLAY_GET_PRIVATE (display);
1727 VADisplayAttribute attr = { 0, };
1731 attr.flags = VA_DISPLAY_ATTRIB_GETTABLE;
1732 status = vaGetDisplayAttributes (priv->display, &attr, 1);
1733 if (!vaapi_check_status (status, "vaGetDisplayAttributes()"))
1735 *value = attr.value;
1740 set_attribute (GstVaapiDisplay * display, VADisplayAttribType type, gint value)
1742 GstVaapiDisplayPrivate *const priv = GST_VAAPI_DISPLAY_GET_PRIVATE (display);
1743 VADisplayAttribute attr = { 0, };
1748 attr.flags = VA_DISPLAY_ATTRIB_SETTABLE;
1749 status = vaSetDisplayAttributes (priv->display, &attr, 1);
1750 if (!vaapi_check_status (status, "vaSetDisplayAttributes()"))
1756 get_render_mode_VADisplayAttribRenderMode (GstVaapiDisplay * display,
1757 GstVaapiRenderMode * pmode)
1759 gint modes, devices;
1761 if (!get_attribute (display, VADisplayAttribRenderDevice, &devices))
1765 if (!get_attribute (display, VADisplayAttribRenderMode, &modes))
1768 /* Favor "overlay" mode since it is the most restrictive one */
1769 if (modes & (VA_RENDER_MODE_LOCAL_OVERLAY | VA_RENDER_MODE_EXTERNAL_OVERLAY))
1770 *pmode = GST_VAAPI_RENDER_MODE_OVERLAY;
1772 *pmode = GST_VAAPI_RENDER_MODE_TEXTURE;
1777 get_render_mode_VADisplayAttribDirectSurface (GstVaapiDisplay * display,
1778 GstVaapiRenderMode * pmode)
1780 #if VA_CHECK_VERSION(0,34,0)
1781 /* VADisplayAttribDirectsurface was removed in VA-API >= 0.34.0 */
1784 gint direct_surface;
1786 if (!get_attribute (display, VADisplayAttribDirectSurface, &direct_surface))
1789 *pmode = GST_VAAPI_RENDER_MODE_OVERLAY;
1791 *pmode = GST_VAAPI_RENDER_MODE_TEXTURE;
1797 get_render_mode_default (GstVaapiDisplay * display, GstVaapiRenderMode * pmode)
1799 GstVaapiDisplayPrivate *const priv = GST_VAAPI_DISPLAY_GET_PRIVATE (display);
1801 switch (priv->display_type) {
1803 case GST_VAAPI_DISPLAY_TYPE_WAYLAND:
1804 /* wl_buffer mapped from VA surface through vaGetSurfaceBufferWl() */
1805 *pmode = GST_VAAPI_RENDER_MODE_OVERLAY;
1809 case GST_VAAPI_DISPLAY_TYPE_DRM:
1810 /* vaGetSurfaceBufferDRM() returns the underlying DRM buffer handle */
1811 *pmode = GST_VAAPI_RENDER_MODE_OVERLAY;
1815 /* This includes VA/X11 and VA/GLX modes */
1816 *pmode = DEFAULT_RENDER_MODE;
1823 * gst_vaapi_display_get_render_mode:
1824 * @display: a #GstVaapiDisplay
1825 * @pmode: return location for the VA @display rendering mode
1827 * Returns the current VA @display rendering mode.
1829 * Return value: %TRUE if VA @display rendering mode could be determined
1832 gst_vaapi_display_get_render_mode (GstVaapiDisplay * display,
1833 GstVaapiRenderMode * pmode)
1835 g_return_val_if_fail (display != NULL, FALSE);
1837 /* Try with render-mode attribute */
1838 if (get_render_mode_VADisplayAttribRenderMode (display, pmode))
1841 /* Try with direct-surface attribute */
1842 if (get_render_mode_VADisplayAttribDirectSurface (display, pmode))
1845 /* Default: determine from the display type */
1846 return get_render_mode_default (display, pmode);
1850 * gst_vaapi_display_set_render_mode:
1851 * @display: a #GstVaapiDisplay
1852 * @mode: the #GstVaapiRenderMode to set
1854 * Sets the VA @display rendering mode to the supplied @mode. This
1855 * function returns %FALSE if the rendering mode could not be set,
1856 * e.g. run-time switching rendering mode is not supported.
1858 * Return value: %TRUE if VA @display rendering @mode could be changed
1859 * to the requested value
1862 gst_vaapi_display_set_render_mode (GstVaapiDisplay * display,
1863 GstVaapiRenderMode mode)
1865 gint modes, devices;
1867 g_return_val_if_fail (display != NULL, FALSE);
1869 if (!get_attribute (display, VADisplayAttribRenderDevice, &devices))
1874 case GST_VAAPI_RENDER_MODE_OVERLAY:
1875 if (devices & VA_RENDER_DEVICE_LOCAL)
1876 modes |= VA_RENDER_MODE_LOCAL_OVERLAY;
1877 if (devices & VA_RENDER_DEVICE_EXTERNAL)
1878 modes |= VA_RENDER_MODE_EXTERNAL_OVERLAY;
1880 case GST_VAAPI_RENDER_MODE_TEXTURE:
1881 if (devices & VA_RENDER_DEVICE_LOCAL)
1882 modes |= VA_RENDER_MODE_LOCAL_GPU;
1883 if (devices & VA_RENDER_DEVICE_EXTERNAL)
1884 modes |= VA_RENDER_MODE_EXTERNAL_GPU;
1889 if (!set_attribute (display, VADisplayAttribRenderMode, modes))
1895 * gst_vaapi_display_get_rotation:
1896 * @display: a #GstVaapiDisplay
1898 * Returns the current VA @display rotation angle. If the VA driver
1899 * does not support "rotation" display attribute, then the display is
1900 * assumed to be un-rotated.
1902 * Return value: the current #GstVaapiRotation value
1905 gst_vaapi_display_get_rotation (GstVaapiDisplay * display)
1909 g_return_val_if_fail (display != NULL, DEFAULT_ROTATION);
1911 if (!get_attribute (display, VADisplayAttribRotation, &value))
1912 value = VA_ROTATION_NONE;
1913 return to_GstVaapiRotation (value);
1917 * gst_vaapi_display_set_rotation:
1918 * @display: a #GstVaapiDisplay
1919 * @rotation: the #GstVaapiRotation value to set
1921 * Sets the VA @display rotation angle to the supplied @rotation
1922 * value. This function returns %FALSE if the rotation angle could not
1923 * be set, e.g. the VA driver does not allow to change the display
1926 * Return value: %TRUE if VA @display rotation angle could be changed
1927 * to the requested value
1930 gst_vaapi_display_set_rotation (GstVaapiDisplay * display,
1931 GstVaapiRotation rotation)
1935 g_return_val_if_fail (display != NULL, FALSE);
1937 value = from_GstVaapiRotation (rotation);
1938 if (!set_attribute (display, VADisplayAttribRotation, value))
1943 /* Get color balance attributes */
1945 get_color_balance (GstVaapiDisplay * display, guint prop_id, gfloat * v)
1947 GParamSpecFloat *const pspec = G_PARAM_SPEC_FLOAT (g_properties[prop_id]);
1948 const GstVaapiProperty *prop;
1949 const VADisplayAttribute *attr;
1953 if (!ensure_properties (display))
1959 prop = find_property_by_pspec (display, &pspec->parent_instance);
1962 attr = &prop->attribute;
1964 if (!get_attribute (display, attr->type, &value))
1967 /* Scale wrt. the medium ("default") value */
1968 out_value = pspec->default_value;
1969 if (value > attr->value)
1970 out_value += ((gfloat) (value - attr->value) /
1971 (attr->max_value - attr->value) *
1972 (pspec->maximum - pspec->default_value));
1973 else if (value < attr->value)
1974 out_value -= ((gfloat) (attr->value - value) /
1975 (attr->value - attr->min_value) *
1976 (pspec->default_value - pspec->minimum));
1981 /* Set color balance attribute */
1983 set_color_balance (GstVaapiDisplay * display, guint prop_id, gfloat v)
1985 GParamSpecFloat *const pspec = G_PARAM_SPEC_FLOAT (g_properties[prop_id]);
1986 const GstVaapiProperty *prop;
1987 const VADisplayAttribute *attr;
1990 if (!ensure_properties (display))
1996 prop = find_property_by_pspec (display, &pspec->parent_instance);
1999 attr = &prop->attribute;
2001 /* Scale wrt. the medium ("default") value */
2002 value = attr->value;
2003 if (v > pspec->default_value)
2004 value += ((v - pspec->default_value) /
2005 (pspec->maximum - pspec->default_value) *
2006 (attr->max_value - attr->value));
2007 else if (v < pspec->default_value)
2008 value -= ((pspec->default_value - v) /
2009 (pspec->default_value - pspec->minimum) *
2010 (attr->value - attr->min_value));
2011 if (!set_attribute (display, attr->type, value))
2016 /* Ensures the VA driver vendor string was copied */
2018 ensure_vendor_string (GstVaapiDisplay * display)
2020 GstVaapiDisplayPrivate *const priv = GST_VAAPI_DISPLAY_GET_PRIVATE (display);
2021 const gchar *vendor_string;
2023 GST_VAAPI_DISPLAY_LOCK (display);
2024 if (!priv->vendor_string) {
2025 vendor_string = vaQueryVendorString (priv->display);
2027 priv->vendor_string = g_strdup (vendor_string);
2029 GST_VAAPI_DISPLAY_UNLOCK (display);
2030 return priv->vendor_string != NULL;
2034 * gst_vaapi_display_get_vendor_string:
2035 * @display: a #GstVaapiDisplay
2037 * Returns the VA driver vendor string attached to the supplied VA @display.
2038 * The @display owns the vendor string, do *not* de-allocate it.
2040 * This function is thread safe.
2042 * Return value: the current #GstVaapiRotation value
2045 gst_vaapi_display_get_vendor_string (GstVaapiDisplay * display)
2047 g_return_val_if_fail (display != NULL, NULL);
2049 if (!ensure_vendor_string (display))
2051 return GST_VAAPI_DISPLAY_GET_PRIVATE (display)->vendor_string;
2055 * gst_vaapi_display_has_opengl:
2056 * @display: a #GstVaapiDisplay
2058 * Returns wether the @display that was created does support OpenGL
2059 * context to be attached.
2061 * This function is thread safe.
2063 * Return value: %TRUE if the @display supports OpenGL context, %FALSE
2067 gst_vaapi_display_has_opengl (GstVaapiDisplay * display)
2069 GstVaapiDisplayClass *klass;
2071 g_return_val_if_fail (display != NULL, FALSE);
2073 klass = GST_VAAPI_DISPLAY_GET_CLASS (display);
2074 return (klass->display_type == GST_VAAPI_DISPLAY_TYPE_GLX ||
2075 klass->display_type == GST_VAAPI_DISPLAY_TYPE_EGL);
2079 * gst_vaapi_display_reset_texture_map:
2080 * @display: a #GstVaapiDisplay
2082 * Reset the internal #GstVaapiTextureMap if available.
2084 * This function is thread safe.
2087 gst_vaapi_display_reset_texture_map (GstVaapiDisplay * display)
2089 GstVaapiDisplayClass *klass;
2090 GstVaapiTextureMap *map;
2092 g_return_if_fail (display != NULL);
2094 if (!gst_vaapi_display_has_opengl (display))
2096 klass = GST_VAAPI_DISPLAY_GET_CLASS (display);
2097 if (!klass->get_texture_map)
2099 if ((map = klass->get_texture_map (display)))
2100 gst_vaapi_texture_map_reset (map);