2 * gstvaapifilter.c - Video processing abstraction
4 * Copyright (C) 2013-2014 Intel Corporation
5 * Author: Gwenole Beauchesne <gwenole.beauchesne@intel.com>
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public License
9 * as published by the Free Software Foundation; either version 2.1
10 * of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free
19 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20 * Boston, MA 02110-1301 USA
26 #include "gstvaapicompat.h"
27 #include "gstvaapifilter.h"
28 #include "gstvaapiutils.h"
29 #include "gstvaapivalue.h"
30 #include "gstvaapiminiobject.h"
31 #include "gstvaapidisplay_priv.h"
32 #include "gstvaapisurface_priv.h"
33 #include "gstvaapiutils_core.h"
35 #define GST_VAAPI_FILTER_CAST(obj) \
36 ((GstVaapiFilter *)(obj))
38 typedef struct _GstVaapiFilterOpData GstVaapiFilterOpData;
39 struct _GstVaapiFilterOpData
54 struct _GstVaapiFilter
57 GstObject parent_instance;
59 GstVaapiDisplay *display;
62 VAContextID va_context;
63 GPtrArray *operations;
64 GstVideoFormat format;
65 GstVaapiScaleMethod scale_method;
66 GstVideoOrientationMethod video_direction;
67 GstVaapiConfigSurfaceAttributes *attribs;
68 GArray *forward_references;
69 GArray *backward_references;
70 GstVaapiRectangle crop_rect;
71 GstVaapiRectangle target_rect;
72 guint use_crop_rect:1;
73 guint use_target_rect:1;
75 guint32 rotation_flags;
77 GstVideoColorimetry input_colorimetry;
78 GstVideoColorimetry output_colorimetry;
80 #if VA_CHECK_VERSION(1,4,0)
81 VAHdrMetaDataHDR10 hdr_meta;
85 typedef struct _GstVaapiFilterClass GstVaapiFilterClass;
86 struct _GstVaapiFilterClass
89 GstObjectClass parent_class;
92 /* Debug category for VaapiFilter */
93 GST_DEBUG_CATEGORY (gst_debug_vaapi_filter);
94 #define GST_CAT_DEFAULT gst_debug_vaapi_filter
97 GST_DEBUG_CATEGORY_INIT (gst_debug_vaapi_filter, "vaapifilter", 0, \
100 G_DEFINE_TYPE_WITH_CODE (GstVaapiFilter, gst_vaapi_filter, GST_TYPE_OBJECT,
103 /* ------------------------------------------------------------------------- */
104 /* --- VPP Types --- */
105 /* ------------------------------------------------------------------------- */
108 gst_vaapi_scale_method_get_type (void)
110 static gsize g_type = 0;
112 static const GEnumValue enum_values[] = {
113 {GST_VAAPI_SCALE_METHOD_DEFAULT,
114 "Default scaling mode", "default"},
115 {GST_VAAPI_SCALE_METHOD_FAST,
116 "Fast scaling mode", "fast"},
117 {GST_VAAPI_SCALE_METHOD_HQ,
118 "High quality scaling mode", "hq"},
122 if (g_once_init_enter (&g_type)) {
124 g_enum_register_static ("GstVaapiScaleMethod", enum_values);
125 g_once_init_leave (&g_type, type);
127 gst_type_mark_as_plugin_api (type, 0);
133 gst_vaapi_deinterlace_method_get_type (void)
135 static gsize g_type = 0;
137 static const GEnumValue enum_values[] = {
138 {GST_VAAPI_DEINTERLACE_METHOD_NONE,
139 "Disable deinterlacing", "none"},
140 {GST_VAAPI_DEINTERLACE_METHOD_BOB,
141 "Bob deinterlacing", "bob"},
142 {GST_VAAPI_DEINTERLACE_METHOD_WEAVE,
143 "Weave deinterlacing", "weave"},
144 {GST_VAAPI_DEINTERLACE_METHOD_MOTION_ADAPTIVE,
145 "Motion adaptive deinterlacing", "motion-adaptive"},
146 {GST_VAAPI_DEINTERLACE_METHOD_MOTION_COMPENSATED,
147 "Motion compensated deinterlacing", "motion-compensated"},
151 if (g_once_init_enter (&g_type)) {
153 g_enum_register_static ("GstVaapiDeinterlaceMethod", enum_values);
154 gst_type_mark_as_plugin_api (type, 0);
155 g_once_init_leave (&g_type, type);
161 gst_vaapi_deinterlace_flags_get_type (void)
163 static gsize g_type = 0;
165 static const GEnumValue enum_values[] = {
166 {GST_VAAPI_DEINTERLACE_FLAG_TFF,
167 "Top-field first", "top-field-first"},
168 {GST_VAAPI_DEINTERLACE_FLAG_ONEFIELD,
169 "One field", "one-field"},
170 {GST_VAAPI_DEINTERLACE_FLAG_TOPFIELD,
171 "Top field", "top-field"},
175 if (g_once_init_enter (&g_type)) {
177 g_enum_register_static ("GstVaapiDeinterlaceFlags", enum_values);
178 gst_type_mark_as_plugin_api (type, 0);
179 g_once_init_leave (&g_type, type);
184 /* ------------------------------------------------------------------------- */
185 /* --- VPP Helpers --- */
186 /* ------------------------------------------------------------------------- */
188 static VAProcFilterType *
189 vpp_get_filters_unlocked (GstVaapiFilter * filter, guint * num_filters_ptr)
191 VAProcFilterType *filters = NULL;
192 guint num_filters = 0;
195 num_filters = VAProcFilterCount;
196 filters = g_malloc_n (num_filters, sizeof (*filters));
200 va_status = vaQueryVideoProcFilters (filter->va_display, filter->va_context,
201 filters, &num_filters);
203 // Try to reallocate to the expected number of filters
204 if (va_status == VA_STATUS_ERROR_MAX_NUM_EXCEEDED) {
205 VAProcFilterType *const new_filters =
206 g_try_realloc_n (filters, num_filters, sizeof (*new_filters));
209 filters = new_filters;
211 va_status = vaQueryVideoProcFilters (filter->va_display,
212 filter->va_context, filters, &num_filters);
214 if (!vaapi_check_status (va_status, "vaQueryVideoProcFilters()"))
217 *num_filters_ptr = num_filters;
228 static VAProcFilterType *
229 vpp_get_filters (GstVaapiFilter * filter, guint * num_filters_ptr)
231 VAProcFilterType *filters;
233 GST_VAAPI_DISPLAY_LOCK (filter->display);
234 filters = vpp_get_filters_unlocked (filter, num_filters_ptr);
235 GST_VAAPI_DISPLAY_UNLOCK (filter->display);
240 vpp_get_filter_caps_unlocked (GstVaapiFilter * filter, VAProcFilterType type,
241 guint cap_size, guint * num_caps_ptr)
247 caps = g_malloc (cap_size);
251 va_status = vaQueryVideoProcFilterCaps (filter->va_display,
252 filter->va_context, type, caps, &num_caps);
254 // Try to reallocate to the expected number of filters
255 if (va_status == VA_STATUS_ERROR_MAX_NUM_EXCEEDED) {
256 gpointer const new_caps = g_try_realloc_n (caps, num_caps, cap_size);
261 va_status = vaQueryVideoProcFilterCaps (filter->va_display,
262 filter->va_context, type, caps, &num_caps);
264 if (!vaapi_check_status (va_status, "vaQueryVideoProcFilterCaps()"))
267 *num_caps_ptr = num_caps;
279 vpp_get_filter_caps (GstVaapiFilter * filter, VAProcFilterType type,
280 guint cap_size, guint * num_caps_ptr)
284 GST_VAAPI_DISPLAY_LOCK (filter->display);
285 caps = vpp_get_filter_caps_unlocked (filter, type, cap_size, num_caps_ptr);
286 GST_VAAPI_DISPLAY_UNLOCK (filter->display);
291 vpp_get_pipeline_caps_unlocked (GstVaapiFilter * filter)
293 #if VA_CHECK_VERSION(1,1,0)
294 VAProcPipelineCaps pipeline_caps = { 0, };
296 VAStatus va_status = vaQueryVideoProcPipelineCaps (filter->va_display,
297 filter->va_context, NULL, 0, &pipeline_caps);
299 if (vaapi_check_status (va_status, "vaQueryVideoProcPipelineCaps()")) {
300 filter->mirror_flags = pipeline_caps.mirror_flags;
301 filter->rotation_flags = pipeline_caps.rotation_flags;
306 filter->mirror_flags = 0;
307 filter->rotation_flags = 0;
311 vpp_get_pipeline_caps (GstVaapiFilter * filter)
313 GST_VAAPI_DISPLAY_LOCK (filter->display);
314 vpp_get_pipeline_caps_unlocked (filter);
315 GST_VAAPI_DISPLAY_UNLOCK (filter->display);
318 /* ------------------------------------------------------------------------- */
319 /* --- VPP Operations --- */
320 /* ------------------------------------------------------------------------- */
322 #define DEFAULT_FORMAT GST_VIDEO_FORMAT_UNKNOWN
324 #define OP_DATA_DEFAULT_VALUE(type, op_data) \
325 g_value_get_##type (g_param_spec_get_default_value (op_data->pspec))
327 #define OP_RET_DEFAULT_VALUE(type, filter, op) \
329 g_return_val_if_fail (filter != NULL, FALSE); \
330 return OP_DATA_DEFAULT_VALUE (type, find_operation (filter, op)); \
342 PROP_FORMAT = GST_VAAPI_FILTER_OP_FORMAT,
343 PROP_CROP = GST_VAAPI_FILTER_OP_CROP,
344 PROP_DENOISE = GST_VAAPI_FILTER_OP_DENOISE,
345 PROP_SHARPEN = GST_VAAPI_FILTER_OP_SHARPEN,
346 PROP_HUE = GST_VAAPI_FILTER_OP_HUE,
347 PROP_SATURATION = GST_VAAPI_FILTER_OP_SATURATION,
348 PROP_BRIGHTNESS = GST_VAAPI_FILTER_OP_BRIGHTNESS,
349 PROP_CONTRAST = GST_VAAPI_FILTER_OP_CONTRAST,
350 PROP_DEINTERLACING = GST_VAAPI_FILTER_OP_DEINTERLACING,
351 PROP_SCALING = GST_VAAPI_FILTER_OP_SCALING,
352 PROP_VIDEO_DIRECTION = GST_VAAPI_FILTER_OP_VIDEO_DIRECTION,
353 PROP_HDR_TONE_MAP = GST_VAAPI_FILTER_OP_HDR_TONE_MAP,
354 #ifndef GST_REMOVE_DEPRECATED
355 PROP_SKINTONE = GST_VAAPI_FILTER_OP_SKINTONE,
357 PROP_SKINTONE_LEVEL = GST_VAAPI_FILTER_OP_SKINTONE_LEVEL,
362 static GParamSpec *g_properties[N_PROPERTIES] = { NULL, };
364 static gsize g_properties_initialized = FALSE;
367 init_properties (void)
370 * GstVaapiFilter:format:
372 * The forced output pixel format, expressed as a #GstVideoFormat.
374 g_properties[PROP_FORMAT] = g_param_spec_enum ("format",
376 "The forced output pixel format",
377 GST_TYPE_VIDEO_FORMAT,
378 DEFAULT_FORMAT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
381 * GstVaapiFilter:crop-rect:
383 * The cropping rectangle, expressed as a #GstVaapiRectangle.
385 g_properties[PROP_CROP] = g_param_spec_boxed ("crop-rect",
386 "Cropping Rectangle",
387 "The cropping rectangle",
388 GST_VAAPI_TYPE_RECTANGLE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
391 * GstVaapiFilter:denoise:
393 * The level of noise reduction to apply.
395 g_properties[PROP_DENOISE] = g_param_spec_float ("denoise",
397 "The level of denoising to apply",
398 0.0, 1.0, 0.0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
401 * GstVaapiFilter:sharpen:
403 * The level of sharpening to apply for positive values, or the
404 * level of blurring for negative values.
406 g_properties[PROP_SHARPEN] = g_param_spec_float ("sharpen",
408 "The level of sharpening/blurring to apply",
409 -1.0, 1.0, 0.0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
412 * GstVaapiFilter:hue:
414 * The color hue, expressed as a float value. Range is -180.0 to
415 * 180.0. Default value is 0.0 and represents no modification.
417 g_properties[PROP_HUE] = g_param_spec_float ("hue",
419 "The color hue value",
420 -180.0, 180.0, 0.0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
423 * GstVaapiFilter:saturation:
425 * The color saturation, expressed as a float value. Range is 0.0 to
426 * 2.0. Default value is 1.0 and represents no modification.
428 g_properties[PROP_SATURATION] = g_param_spec_float ("saturation",
430 "The color saturation value",
431 0.0, 2.0, 1.0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
434 * GstVaapiFilter:brightness:
436 * The color brightness, expressed as a float value. Range is -1.0
437 * to 1.0. Default value is 0.0 and represents no modification.
439 g_properties[PROP_BRIGHTNESS] = g_param_spec_float ("brightness",
441 "The color brightness value",
442 -1.0, 1.0, 0.0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
445 * GstVaapiFilter:contrast:
447 * The color contrast, expressed as a float value. Range is 0.0 to
448 * 2.0. Default value is 1.0 and represents no modification.
450 g_properties[PROP_CONTRAST] = g_param_spec_float ("contrast",
452 "The color contrast value",
453 0.0, 2.0, 1.0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
456 * GstVaapiFilter:deinterlace-method:
458 * The deinterlacing algorithm to apply, expressed a an enum
459 * value. See #GstVaapiDeinterlaceMethod.
461 g_properties[PROP_DEINTERLACING] = g_param_spec_enum ("deinterlace",
462 "Deinterlacing Method",
463 "Deinterlacing method to apply",
464 GST_VAAPI_TYPE_DEINTERLACE_METHOD,
465 GST_VAAPI_DEINTERLACE_METHOD_NONE,
466 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
469 * GstVaapiFilter:scale-method:
471 * The scaling method to use, expressed as an enum value. See
472 * #GstVaapiScaleMethod.
474 g_properties[PROP_SCALING] = g_param_spec_enum ("scale-method",
476 "Scaling method to use",
477 GST_VAAPI_TYPE_SCALE_METHOD,
478 GST_VAAPI_SCALE_METHOD_DEFAULT,
479 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
482 * GstVaapiFilter:video-direction:
484 * The video-direction to use, expressed as an enum value. See
485 * #GstVideoOrientationMethod.
487 g_properties[PROP_VIDEO_DIRECTION] = g_param_spec_enum ("video-direction",
489 "Video direction: rotation and flipping",
490 GST_TYPE_VIDEO_ORIENTATION_METHOD,
491 GST_VIDEO_ORIENTATION_IDENTITY,
492 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
495 * GstVaapiFilter:tone-map:
497 * Apply HDR tone mapping
499 g_properties[PROP_HDR_TONE_MAP] = g_param_spec_boolean ("hdr-tone-map",
501 "Apply HDR tone mapping",
502 FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
504 #ifndef GST_REMOVE_DEPRECATED
506 * GstVaapiFilter:skin-tone-enhancement:
508 * Apply the skin tone enhancement algorithm.
510 g_properties[PROP_SKINTONE] = g_param_spec_boolean ("skin-tone-enhancement",
511 "Skin tone enhancement",
512 "Apply the skin tone enhancement algorithm",
513 FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
517 * GstVaapiFilter:skin-tone-enhancement-level:
519 * Apply the skin tone enhancement algorithm with specified value.
521 g_properties[PROP_SKINTONE_LEVEL] =
522 g_param_spec_uint ("skin-tone-enhancement-level",
523 "Skin tone enhancement level",
524 "Apply the skin tone enhancement algorithm with specified level", 0, 9, 3,
525 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
529 ensure_properties (void)
531 if (g_once_init_enter (&g_properties_initialized)) {
533 g_once_init_leave (&g_properties_initialized, TRUE);
538 op_data_free (GstVaapiFilterOpData * op_data)
540 g_free (op_data->va_caps);
541 g_slice_free (GstVaapiFilterOpData, op_data);
544 static inline gpointer
545 op_data_new (GstVaapiFilterOp op, GParamSpec * pspec)
547 GstVaapiFilterOpData *op_data;
549 op_data = g_slice_new0 (GstVaapiFilterOpData);
554 op_data->pspec = pspec;
555 g_atomic_int_set (&op_data->ref_count, 1);
556 op_data->va_buffer = VA_INVALID_ID;
559 case GST_VAAPI_FILTER_OP_HDR_TONE_MAP:
560 #if VA_CHECK_VERSION(1,4,0)
561 /* Only HDR10 tone mapping is supported */
562 op_data->va_type = VAProcFilterHighDynamicRangeToneMapping;
563 op_data->va_subtype = VAProcHighDynamicRangeMetadataHDR10;
564 op_data->va_cap_size = sizeof (VAProcFilterCapHighDynamicRange);
565 op_data->va_buffer_size =
566 sizeof (VAProcFilterParameterBufferHDRToneMapping);
571 case GST_VAAPI_FILTER_OP_FORMAT:
572 case GST_VAAPI_FILTER_OP_CROP:
573 case GST_VAAPI_FILTER_OP_SCALING:
574 case GST_VAAPI_FILTER_OP_VIDEO_DIRECTION:
575 op_data->va_type = VAProcFilterNone;
577 case GST_VAAPI_FILTER_OP_DENOISE:
578 op_data->va_type = VAProcFilterNoiseReduction;
579 op_data->va_cap_size = sizeof (VAProcFilterCap);
580 op_data->va_buffer_size = sizeof (VAProcFilterParameterBuffer);
582 case GST_VAAPI_FILTER_OP_SHARPEN:
583 op_data->va_type = VAProcFilterSharpening;
584 op_data->va_cap_size = sizeof (VAProcFilterCap);
585 op_data->va_buffer_size = sizeof (VAProcFilterParameterBuffer);
587 #ifndef GST_REMOVE_DEPRECATED
588 case GST_VAAPI_FILTER_OP_SKINTONE:
590 case GST_VAAPI_FILTER_OP_SKINTONE_LEVEL:
591 op_data->va_type = VAProcFilterSkinToneEnhancement;
592 op_data->va_buffer_size = sizeof (VAProcFilterParameterBuffer);
594 case GST_VAAPI_FILTER_OP_HUE:
595 op_data->va_subtype = VAProcColorBalanceHue;
596 goto op_colorbalance;
597 case GST_VAAPI_FILTER_OP_SATURATION:
598 op_data->va_subtype = VAProcColorBalanceSaturation;
599 goto op_colorbalance;
600 case GST_VAAPI_FILTER_OP_BRIGHTNESS:
601 op_data->va_subtype = VAProcColorBalanceBrightness;
602 goto op_colorbalance;
603 case GST_VAAPI_FILTER_OP_CONTRAST:
604 op_data->va_subtype = VAProcColorBalanceContrast;
606 op_data->va_type = VAProcFilterColorBalance;
607 op_data->va_cap_size = sizeof (VAProcFilterCapColorBalance);
608 op_data->va_buffer_size =
609 sizeof (VAProcFilterParameterBufferColorBalance);
611 case GST_VAAPI_FILTER_OP_DEINTERLACING:
612 op_data->va_type = VAProcFilterDeinterlacing;
613 op_data->va_cap_size = sizeof (VAProcFilterCapDeinterlacing);
614 op_data->va_buffer_size =
615 sizeof (VAProcFilterParameterBufferDeinterlacing);
618 g_assert (0 && "unsupported operation");
626 op_data_free (op_data);
631 static inline gpointer
632 op_data_ref (gpointer data)
634 GstVaapiFilterOpData *const op_data = data;
636 g_return_val_if_fail (op_data != NULL, NULL);
638 g_atomic_int_inc (&op_data->ref_count);
643 op_data_unref (gpointer data)
645 GstVaapiFilterOpData *const op_data = data;
647 g_return_if_fail (op_data != NULL);
648 g_return_if_fail (op_data->ref_count > 0);
650 if (g_atomic_int_dec_and_test (&op_data->ref_count))
651 op_data_free (op_data);
654 /* Ensure capability info is set up for the VA filter we are interested in */
656 op_data_ensure_caps (GstVaapiFilterOpData * op_data, gpointer filter_caps,
657 guint num_filter_caps)
659 guchar *filter_cap = filter_caps;
660 guint i, va_num_caps = num_filter_caps;
662 // Find the VA filter cap matching the op info sub-type
663 if (op_data->va_subtype) {
664 for (i = 0; i < num_filter_caps; i++) {
665 /* XXX: sub-type shall always be the first field */
666 if (op_data->va_subtype == *(guint *) filter_cap) {
670 filter_cap += op_data->va_cap_size;
672 if (i == num_filter_caps)
676 op_data->va_caps = g_memdup2 (filter_cap, op_data->va_cap_size * va_num_caps);
677 if (!op_data->va_caps)
680 op_data->va_num_caps = va_num_caps;
684 /* Scale the filter value wrt. library spec and VA driver spec */
686 op_data_get_value_float (GstVaapiFilterOpData * op_data,
687 const VAProcFilterValueRange * range, gfloat value, gfloat * out_value_ptr)
689 GParamSpecFloat *const pspec = G_PARAM_SPEC_FLOAT (op_data->pspec);
692 g_return_val_if_fail (range != NULL, FALSE);
693 g_return_val_if_fail (out_value_ptr != NULL, FALSE);
695 if (value < pspec->minimum || value > pspec->maximum)
698 // Scale wrt. the medium ("default") value
699 out_value = range->default_value;
700 if (value > pspec->default_value)
701 out_value += ((value - pspec->default_value) /
702 (pspec->maximum - pspec->default_value) *
703 (range->max_value - range->default_value));
704 else if (value < pspec->default_value)
705 out_value -= ((pspec->default_value - value) /
706 (pspec->default_value - pspec->minimum) *
707 (range->default_value - range->min_value));
709 *out_value_ptr = out_value;
713 /* Get default list of operations supported by the library */
715 get_operations_default (void)
720 ops = g_ptr_array_new_full (N_PROPERTIES, op_data_unref);
724 ensure_properties ();
726 for (i = 0; i < N_PROPERTIES; i++) {
727 GstVaapiFilterOpData *op_data;
728 GParamSpec *const pspec = g_properties[i];
732 op_data = op_data_new (i, pspec);
735 g_ptr_array_add (ops, op_data);
742 g_ptr_array_unref (ops);
747 /* Get the ordered list of operations, based on VA/VPP queries */
749 get_operations_ordered (GstVaapiFilter * filter, GPtrArray * default_ops)
752 VAProcFilterType *filters;
753 gpointer filter_caps = NULL;
754 guint i, j, num_filters, num_filter_caps = 0;
756 ops = g_ptr_array_new_full (default_ops->len, op_data_unref);
760 filters = vpp_get_filters (filter, &num_filters);
764 // Append virtual ops first, i.e. those without an associated VA filter
765 for (i = 0; i < default_ops->len; i++) {
766 GstVaapiFilterOpData *const op_data = g_ptr_array_index (default_ops, i);
767 if (op_data->va_type == VAProcFilterNone)
768 g_ptr_array_add (ops, op_data_ref (op_data));
771 // Append ops, while preserving the VA filters ordering
772 for (i = 0; i < num_filters; i++) {
773 const VAProcFilterType va_type = filters[i];
774 if (va_type == VAProcFilterNone)
777 for (j = 0; j < default_ops->len; j++) {
778 GstVaapiFilterOpData *const op_data = g_ptr_array_index (default_ops, j);
779 if (op_data->va_type != va_type)
782 if (op_data->va_cap_size == 0) { /* no caps, like skintone */
783 g_ptr_array_add (ops, op_data_ref (op_data));
788 filter_caps = vpp_get_filter_caps (filter, va_type,
789 op_data->va_cap_size, &num_filter_caps);
793 if (!op_data_ensure_caps (op_data, filter_caps, num_filter_caps))
795 g_ptr_array_add (ops, op_data_ref (op_data));
801 vpp_get_pipeline_caps (filter);
803 if (filter->operations)
804 g_ptr_array_unref (filter->operations);
805 filter->operations = g_ptr_array_ref (ops);
808 g_ptr_array_unref (default_ops);
814 g_free (filter_caps);
816 g_ptr_array_unref (ops);
817 g_ptr_array_unref (default_ops);
822 /* Determine the set of supported VPP operations by the specific
823 filter, or known to this library if filter is NULL */
825 get_operations (GstVaapiFilter * filter)
829 if (filter && filter->operations)
830 return g_ptr_array_ref (filter->operations);
832 ops = get_operations_default ();
835 return filter ? get_operations_ordered (filter, ops) : ops;
838 /* Ensure the set of supported VPP operations is cached into the
839 GstVaapiFilter::operations member */
840 static inline gboolean
841 ensure_operations (GstVaapiFilter * filter)
848 if (filter->operations)
851 ops = get_operations (filter);
855 g_ptr_array_unref (ops);
859 /* Find whether the VPP operation is supported or not */
860 static GstVaapiFilterOpData *
861 find_operation (GstVaapiFilter * filter, GstVaapiFilterOp op)
865 if (!ensure_operations (filter))
868 for (i = 0; i < filter->operations->len; i++) {
869 GstVaapiFilterOpData *const op_data =
870 g_ptr_array_index (filter->operations, i);
871 if (op_data->op == op)
877 /* Ensure the operation's VA buffer is allocated */
878 static inline gboolean
879 op_ensure_n_elements_buffer (GstVaapiFilter * filter,
880 GstVaapiFilterOpData * op_data, gint op_num)
882 if (G_LIKELY (op_data->va_buffer != VA_INVALID_ID))
884 return vaapi_create_n_elements_buffer (filter->va_display, filter->va_context,
885 VAProcFilterParameterBufferType, op_data->va_buffer_size, NULL,
886 &op_data->va_buffer, NULL, op_num);
889 static inline gboolean
890 op_ensure_buffer (GstVaapiFilter * filter, GstVaapiFilterOpData * op_data)
892 return op_ensure_n_elements_buffer (filter, op_data, 1);
895 /* Update a generic filter (float value) */
897 op_set_generic_unlocked (GstVaapiFilter * filter,
898 GstVaapiFilterOpData * op_data, gfloat value)
900 VAProcFilterParameterBuffer *buf;
901 VAProcFilterCap *filter_cap;
904 if (!op_data || !op_ensure_buffer (filter, op_data))
907 op_data->is_enabled = (value != OP_DATA_DEFAULT_VALUE (float, op_data));
908 if (!op_data->is_enabled)
911 filter_cap = op_data->va_caps;
912 if (!op_data_get_value_float (op_data, &filter_cap->range, value, &va_value))
915 buf = vaapi_map_buffer (filter->va_display, op_data->va_buffer);
919 buf->type = op_data->va_type;
920 buf->value = va_value;
921 vaapi_unmap_buffer (filter->va_display, op_data->va_buffer, NULL);
925 static inline gboolean
926 op_set_generic (GstVaapiFilter * filter, GstVaapiFilterOpData * op_data,
929 gboolean success = FALSE;
931 GST_VAAPI_DISPLAY_LOCK (filter->display);
932 success = op_set_generic_unlocked (filter, op_data, value);
933 GST_VAAPI_DISPLAY_UNLOCK (filter->display);
937 /* Update the color balance filter */
938 #define COLOR_BALANCE_NUM \
939 GST_VAAPI_FILTER_OP_CONTRAST - GST_VAAPI_FILTER_OP_HUE + 1
942 op_set_color_balance_unlocked (GstVaapiFilter * filter,
943 GstVaapiFilterOpData * op_data, gfloat value)
945 VAProcFilterParameterBufferColorBalance *buf;
946 VAProcFilterCapColorBalance *filter_cap;
949 GstVaapiFilterOpData *color_data[COLOR_BALANCE_NUM];
950 GstVaapiFilterOpData *enabled_data = NULL;
956 /* collect all the Color Balance operators and find the first
958 for (i = 0; i < COLOR_BALANCE_NUM; i++) {
959 color_data[i] = find_operation (filter, GST_VAAPI_FILTER_OP_HUE + i);
963 if (!enabled_data && color_data[i]->is_enabled)
964 enabled_data = color_data[i];
967 /* If there's no enabled operators let's enable this one.
969 * HACK: This operator will be the only one with an allocated buffer
970 * which will store all the color balance operators.
974 if (value == OP_DATA_DEFAULT_VALUE (float, op_data))
978 if (!op_ensure_n_elements_buffer (filter, op_data, COLOR_BALANCE_NUM))
981 enabled_data = op_data;
983 buf = vaapi_map_buffer (filter->va_display, enabled_data->va_buffer);
987 /* Write all the color balance operator values in the buffer. --
988 * Use the default value for all the operators except the set
990 for (i = 0; i < COLOR_BALANCE_NUM; i++) {
991 buf[i].type = color_data[i]->va_type;
992 buf[i].attrib = color_data[i]->va_subtype;
994 va_value = OP_DATA_DEFAULT_VALUE (float, color_data[i]);
995 if (color_data[i]->op == op_data->op) {
996 filter_cap = color_data[i]->va_caps;
997 /* fail but ignore current value and set default one */
998 if (!op_data_get_value_float (color_data[i], &filter_cap->range, value,
1003 buf[i].value = va_value;
1006 enabled_data->is_enabled = 1;
1008 /* There's already one operator enabled, *in theory* with a
1009 * buffer associated. */
1010 if (G_UNLIKELY (enabled_data->va_buffer == VA_INVALID_ID))
1013 filter_cap = op_data->va_caps;
1014 if (!op_data_get_value_float (op_data, &filter_cap->range, value,
1018 buf = vaapi_map_buffer (filter->va_display, enabled_data->va_buffer);
1022 buf[op_data->op - GST_VAAPI_FILTER_OP_HUE].value = va_value;
1025 vaapi_unmap_buffer (filter->va_display, enabled_data->va_buffer, NULL);
1030 static inline gboolean
1031 op_set_color_balance (GstVaapiFilter * filter, GstVaapiFilterOpData * op_data,
1034 gboolean success = FALSE;
1036 GST_VAAPI_DISPLAY_LOCK (filter->display);
1037 success = op_set_color_balance_unlocked (filter, op_data, value);
1038 GST_VAAPI_DISPLAY_UNLOCK (filter->display);
1042 /* Update deinterlace filter */
1044 op_set_deinterlace_unlocked (GstVaapiFilter * filter,
1045 GstVaapiFilterOpData * op_data, GstVaapiDeinterlaceMethod method,
1048 VAProcFilterParameterBufferDeinterlacing *buf;
1049 const VAProcFilterCapDeinterlacing *filter_caps;
1050 VAProcDeinterlacingType algorithm;
1053 if (!op_data || !op_ensure_buffer (filter, op_data))
1056 op_data->is_enabled = (method != GST_VAAPI_DEINTERLACE_METHOD_NONE);
1057 if (!op_data->is_enabled)
1060 algorithm = from_GstVaapiDeinterlaceMethod (method);
1061 for (i = 0, filter_caps = op_data->va_caps; i < op_data->va_num_caps; i++) {
1062 if (filter_caps[i].type == algorithm)
1065 if (i == op_data->va_num_caps)
1068 buf = vaapi_map_buffer (filter->va_display, op_data->va_buffer);
1072 buf->type = op_data->va_type;
1073 buf->algorithm = algorithm;
1074 buf->flags = from_GstVaapiDeinterlaceFlags (flags);
1075 vaapi_unmap_buffer (filter->va_display, op_data->va_buffer, NULL);
1079 static inline gboolean
1080 op_set_deinterlace (GstVaapiFilter * filter, GstVaapiFilterOpData * op_data,
1081 GstVaapiDeinterlaceMethod method, guint flags)
1083 gboolean success = FALSE;
1085 GST_VAAPI_DISPLAY_LOCK (filter->display);
1086 success = op_set_deinterlace_unlocked (filter, op_data, method, flags);
1087 GST_VAAPI_DISPLAY_UNLOCK (filter->display);
1091 /* Update skin tone enhancement level */
1093 op_set_skintone_level_unlocked (GstVaapiFilter * filter,
1094 GstVaapiFilterOpData * op_data, guint value)
1096 VAProcFilterParameterBuffer *buf;
1098 if (!op_data || !op_ensure_buffer (filter, op_data))
1101 op_data->is_enabled = 1;
1103 buf = vaapi_map_buffer (filter->va_display, op_data->va_buffer);
1106 buf->type = op_data->va_type;
1108 vaapi_unmap_buffer (filter->va_display, op_data->va_buffer, NULL);
1112 static inline gboolean
1113 op_set_skintone_level (GstVaapiFilter * filter,
1114 GstVaapiFilterOpData * op_data, guint value)
1116 gboolean success = FALSE;
1118 GST_VAAPI_DISPLAY_LOCK (filter->display);
1119 success = op_set_skintone_level_unlocked (filter, op_data, value);
1120 GST_VAAPI_DISPLAY_UNLOCK (filter->display);
1124 #ifndef GST_REMOVE_DEPRECATED
1125 /* Update skin tone enhancement */
1127 op_set_skintone_unlocked (GstVaapiFilter * filter,
1128 GstVaapiFilterOpData * op_data, gboolean value)
1134 op_data->is_enabled = 0;
1138 return op_set_skintone_level_unlocked (filter, op_data, 3);
1141 static inline gboolean
1142 op_set_skintone (GstVaapiFilter * filter, GstVaapiFilterOpData * op_data,
1145 gboolean success = FALSE;
1147 GST_VAAPI_DISPLAY_LOCK (filter->display);
1148 success = op_set_skintone_unlocked (filter, op_data, enhance);
1149 GST_VAAPI_DISPLAY_UNLOCK (filter->display);
1155 op_set_hdr_tone_map_unlocked (GstVaapiFilter * filter,
1156 GstVaapiFilterOpData * op_data, gboolean value)
1158 #if VA_CHECK_VERSION(1,4,0)
1159 const VAProcFilterCapHighDynamicRange *filter_caps;
1166 op_data->is_enabled = 0;
1170 if (!op_ensure_buffer (filter, op_data))
1173 for (i = 0, filter_caps = op_data->va_caps; i < op_data->va_num_caps; i++) {
1174 if (filter_caps[i].metadata_type == op_data->va_subtype &&
1175 (filter_caps[i].caps_flag & VA_TONE_MAPPING_HDR_TO_SDR))
1178 if (i == op_data->va_num_caps)
1181 op_data->is_enabled = 1;
1189 static inline gboolean
1190 op_set_hdr_tone_map (GstVaapiFilter * filter, GstVaapiFilterOpData * op_data,
1193 gboolean success = FALSE;
1194 GST_VAAPI_DISPLAY_LOCK (filter->display);
1195 success = op_set_hdr_tone_map_unlocked (filter, op_data, value);
1196 GST_VAAPI_DISPLAY_UNLOCK (filter->display);
1202 deint_refs_set (GArray * refs, GstVaapiSurface ** surfaces, guint num_surfaces)
1206 if (num_surfaces > 0 && !surfaces)
1209 for (i = 0; i < num_surfaces; i++)
1210 g_array_append_val (refs, GST_VAAPI_SURFACE_ID (surfaces[i]));
1215 deint_refs_clear (GArray * refs)
1218 g_array_remove_range (refs, 0, refs->len);
1222 deint_refs_clear_all (GstVaapiFilter * filter)
1224 deint_refs_clear (filter->forward_references);
1225 deint_refs_clear (filter->backward_references);
1228 /* ------------------------------------------------------------------------- */
1229 /* --- Surface Attribs --- */
1230 /* ------------------------------------------------------------------------- */
1233 ensure_attributes (GstVaapiFilter * filter)
1235 if (G_LIKELY (filter->attribs))
1238 filter->attribs = gst_vaapi_config_surface_attributes_get (filter->display,
1240 return (filter->attribs != NULL);
1243 static inline gboolean
1244 is_special_format (GstVideoFormat format)
1246 return format == GST_VIDEO_FORMAT_UNKNOWN ||
1247 format == GST_VIDEO_FORMAT_ENCODED;
1251 find_format (GstVaapiFilter * filter, GstVideoFormat format)
1256 formats = filter->attribs->formats;
1257 if (is_special_format (format) || !formats)
1260 for (i = 0; i < formats->len; i++) {
1261 if (g_array_index (formats, GstVideoFormat, i) == format)
1267 /* ------------------------------------------------------------------------- */
1268 /* --- Interface --- */
1269 /* ------------------------------------------------------------------------- */
1272 gst_vaapi_filter_init (GstVaapiFilter * filter)
1274 filter->va_config = VA_INVALID_ID;
1275 filter->va_context = VA_INVALID_ID;
1276 filter->format = DEFAULT_FORMAT;
1278 filter->forward_references =
1279 g_array_sized_new (FALSE, FALSE, sizeof (VASurfaceID), 4);
1281 filter->backward_references =
1282 g_array_sized_new (FALSE, FALSE, sizeof (VASurfaceID), 4);
1286 gst_vaapi_filter_initialize (GstVaapiFilter * filter)
1290 if (!filter->display)
1293 va_status = vaCreateConfig (filter->va_display, VAProfileNone,
1294 VAEntrypointVideoProc, NULL, 0, &filter->va_config);
1295 if (!vaapi_check_status (va_status, "vaCreateConfig() [VPP]"))
1298 va_status = vaCreateContext (filter->va_display, filter->va_config, 0, 0, 0,
1299 NULL, 0, &filter->va_context);
1300 if (!vaapi_check_status (va_status, "vaCreateContext() [VPP]"))
1303 gst_video_colorimetry_from_string (&filter->input_colorimetry, NULL);
1304 gst_video_colorimetry_from_string (&filter->output_colorimetry, NULL);
1310 gst_vaapi_filter_finalize (GObject * object)
1312 GstVaapiFilter *const filter = GST_VAAPI_FILTER (object);
1315 if (!filter->display)
1318 GST_VAAPI_DISPLAY_LOCK (filter->display);
1319 if (filter->operations) {
1320 for (i = 0; i < filter->operations->len; i++) {
1321 GstVaapiFilterOpData *const op_data =
1322 g_ptr_array_index (filter->operations, i);
1323 vaapi_destroy_buffer (filter->va_display, &op_data->va_buffer);
1325 g_ptr_array_unref (filter->operations);
1326 filter->operations = NULL;
1329 if (filter->va_context != VA_INVALID_ID) {
1330 vaDestroyContext (filter->va_display, filter->va_context);
1331 filter->va_context = VA_INVALID_ID;
1334 if (filter->va_config != VA_INVALID_ID) {
1335 vaDestroyConfig (filter->va_display, filter->va_config);
1336 filter->va_config = VA_INVALID_ID;
1338 GST_VAAPI_DISPLAY_UNLOCK (filter->display);
1339 gst_vaapi_display_replace (&filter->display, NULL);
1342 if (filter->forward_references) {
1343 g_array_unref (filter->forward_references);
1344 filter->forward_references = NULL;
1347 if (filter->backward_references) {
1348 g_array_unref (filter->backward_references);
1349 filter->backward_references = NULL;
1352 if (filter->attribs) {
1353 gst_vaapi_config_surface_attributes_free (filter->attribs);
1354 filter->attribs = NULL;
1357 G_OBJECT_CLASS (gst_vaapi_filter_parent_class)->finalize (object);
1361 gst_vaapi_filter_set_property (GObject * object, guint property_id,
1362 const GValue * value, GParamSpec * pspec)
1364 GstVaapiFilter *const filter = GST_VAAPI_FILTER (object);
1366 switch (property_id) {
1368 GstVaapiDisplay *display = g_value_get_object (value);;
1371 if (GST_VAAPI_DISPLAY_HAS_VPP (display)) {
1372 filter->display = gst_object_ref (display);
1373 filter->va_display = GST_VAAPI_DISPLAY_VADISPLAY (filter->display);
1375 GST_WARNING_OBJECT (filter, "VA display doesn't support VPP");
1381 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
1386 gst_vaapi_filter_get_property (GObject * object, guint property_id,
1387 GValue * value, GParamSpec * pspec)
1389 GstVaapiFilter *const filter = GST_VAAPI_FILTER (object);
1391 switch (property_id) {
1393 g_value_set_object (value, filter->display);
1396 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
1401 gst_vaapi_filter_class_init (GstVaapiFilterClass * klass)
1403 GObjectClass *const object_class = G_OBJECT_CLASS (klass);
1405 object_class->set_property = gst_vaapi_filter_set_property;
1406 object_class->get_property = gst_vaapi_filter_get_property;
1407 object_class->finalize = gst_vaapi_filter_finalize;
1410 * GstVaapiFilter:display:
1412 * #GstVaapiDisplay to be used.
1414 g_object_class_install_property (object_class, PROP_DISPLAY,
1415 g_param_spec_object ("display", "Gst VA-API Display",
1416 "The VA-API display object to use", GST_TYPE_VAAPI_DISPLAY,
1417 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_NAME));
1421 * gst_vaapi_filter_new:
1422 * @display: a #GstVaapiDisplay
1424 * Creates a new #GstVaapiFilter set up to operate in "identity"
1425 * mode. This means that no other operation than scaling is performed.
1427 * Return value: the newly created #GstVaapiFilter object
1430 gst_vaapi_filter_new (GstVaapiDisplay * display)
1432 GstVaapiFilter *filter;
1434 filter = g_object_new (GST_TYPE_VAAPI_FILTER, "display", display, NULL);
1435 if (!gst_vaapi_filter_initialize (filter))
1442 gst_object_unref (filter);
1448 * gst_vaapi_filter_replace:
1449 * @old_filter_ptr: a pointer to a #GstVaapiFilter
1450 * @new_filter: a #GstVaapiFilter
1452 * Atomically replaces the filter held in @old_filter_ptr with
1453 * @new_filter. This means that @old_filter_ptr shall reference a
1454 * valid filter. However, @new_filter can be NULL.
1457 gst_vaapi_filter_replace (GstVaapiFilter ** old_filter_ptr,
1458 GstVaapiFilter * new_filter)
1460 g_return_if_fail (old_filter_ptr != NULL);
1462 gst_object_replace ((GstObject **) old_filter_ptr, GST_OBJECT (new_filter));
1466 * gst_vaapi_filter_get_operations:
1467 * @filter: a #GstVaapiFilter, or %NULL
1469 * Determines the set of supported operations for video processing.
1470 * The caller owns an extra reference to the resulting array of
1471 * #GstVaapiFilterOpInfo elements, so it shall be released with
1472 * g_ptr_array_unref() after usage.
1474 * If @filter is %NULL, then this function returns the video
1475 * processing operations supported by this library.
1477 * Return value: the set of supported operations, or %NULL if an error
1481 gst_vaapi_filter_get_operations (GstVaapiFilter * filter)
1483 return get_operations (filter);
1487 * gst_vaapi_filter_has_operation:
1488 * @filter: a #GstVaapiFilter
1489 * @op: a #GstVaapiFilterOp
1491 * Determines whether the underlying VA driver advertises support for
1492 * the supplied operation @op.
1494 * Return value: %TRUE if the specified operation may be supported by
1495 * the underlying hardware, %FALSE otherwise
1498 gst_vaapi_filter_has_operation (GstVaapiFilter * filter, GstVaapiFilterOp op)
1500 g_return_val_if_fail (filter != NULL, FALSE);
1502 return find_operation (filter, op) != NULL;
1506 * gst_vaapi_filter_use_operation:
1507 * @filter: a #GstVaapiFilter
1508 * @op: a #GstVaapiFilterOp
1510 * Determines whether the supplied operation @op was already enabled
1511 * through a prior call to gst_vaapi_filter_set_operation() or any
1512 * other operation-specific function.
1514 * Note: should an operation be set to its default value, this means
1515 * that it is actually not enabled.
1517 * Return value: %TRUE if the specified operation was already enabled,
1521 gst_vaapi_filter_use_operation (GstVaapiFilter * filter, GstVaapiFilterOp op)
1523 GstVaapiFilterOpData *op_data;
1525 g_return_val_if_fail (filter != NULL, FALSE);
1527 op_data = find_operation (filter, op);
1530 return op_data->is_enabled;
1534 * gst_vaapi_filter_set_operation:
1535 * @filter: a #GstVaapiFilter
1536 * @op: a #GstVaapiFilterOp
1537 * @value: the @op settings
1539 * Enable the specified operation @op to be performed during video
1540 * processing, i.e. in gst_vaapi_filter_process(). The @value argument
1541 * specifies the operation settings. e.g. deinterlacing method for
1542 * deinterlacing, denoising level for noise reduction, etc.
1544 * If @value is %NULL, then this function resets the operation
1545 * settings to their default values.
1547 * Return value: %TRUE if the specified operation may be supported,
1551 gst_vaapi_filter_set_operation (GstVaapiFilter * filter, GstVaapiFilterOp op,
1552 const GValue * value)
1554 GstVaapiFilterOpData *op_data;
1556 g_return_val_if_fail (filter != NULL, FALSE);
1558 op_data = find_operation (filter, op);
1562 if (value && !G_VALUE_HOLDS (value, G_PARAM_SPEC_VALUE_TYPE (op_data->pspec)))
1566 case GST_VAAPI_FILTER_OP_FORMAT:
1567 return gst_vaapi_filter_set_format (filter, value ?
1568 g_value_get_enum (value) : DEFAULT_FORMAT);
1569 case GST_VAAPI_FILTER_OP_CROP:
1570 return gst_vaapi_filter_set_cropping_rectangle (filter, value ?
1571 g_value_get_boxed (value) : NULL);
1572 case GST_VAAPI_FILTER_OP_DENOISE:
1573 case GST_VAAPI_FILTER_OP_SHARPEN:
1574 return op_set_generic (filter, op_data,
1575 (value ? g_value_get_float (value) :
1576 OP_DATA_DEFAULT_VALUE (float, op_data)));
1577 case GST_VAAPI_FILTER_OP_HUE:
1578 case GST_VAAPI_FILTER_OP_SATURATION:
1579 case GST_VAAPI_FILTER_OP_BRIGHTNESS:
1580 case GST_VAAPI_FILTER_OP_CONTRAST:
1581 return op_set_color_balance (filter, op_data,
1582 (value ? g_value_get_float (value) :
1583 OP_DATA_DEFAULT_VALUE (float, op_data)));
1584 case GST_VAAPI_FILTER_OP_DEINTERLACING:
1585 return op_set_deinterlace (filter, op_data,
1586 (value ? g_value_get_enum (value) :
1587 OP_DATA_DEFAULT_VALUE (enum, op_data)), 0);
1589 case GST_VAAPI_FILTER_OP_SCALING:
1590 return gst_vaapi_filter_set_scaling (filter,
1591 (value ? g_value_get_enum (value) :
1592 OP_DATA_DEFAULT_VALUE (enum, op_data)));
1593 #ifndef GST_REMOVE_DEPRECATED
1594 case GST_VAAPI_FILTER_OP_SKINTONE:
1595 return op_set_skintone (filter, op_data,
1596 (value ? g_value_get_boolean (value) :
1597 OP_DATA_DEFAULT_VALUE (boolean, op_data)));
1599 case GST_VAAPI_FILTER_OP_SKINTONE_LEVEL:
1600 return op_set_skintone_level (filter, op_data,
1601 (value ? g_value_get_uint (value) :
1602 OP_DATA_DEFAULT_VALUE (uint, op_data)));
1603 case GST_VAAPI_FILTER_OP_VIDEO_DIRECTION:
1604 return gst_vaapi_filter_set_video_direction (filter,
1605 (value ? g_value_get_enum (value) :
1606 OP_DATA_DEFAULT_VALUE (enum, op_data)));
1607 case GST_VAAPI_FILTER_OP_HDR_TONE_MAP:
1608 return op_set_hdr_tone_map (filter, op_data,
1609 (value ? g_value_get_boolean (value) :
1610 OP_DATA_DEFAULT_VALUE (boolean, op_data)));
1617 #if VA_CHECK_VERSION(1,2,0)
1619 fill_color_standard (GstVideoColorimetry * colorimetry,
1620 VAProcColorStandardType * type, VAProcColorProperties * properties)
1622 *type = from_GstVideoColorimetry (colorimetry);
1624 properties->colour_primaries =
1625 gst_video_color_primaries_to_iso (colorimetry->primaries);
1626 properties->transfer_characteristics =
1627 gst_video_transfer_function_to_iso (colorimetry->transfer);
1628 properties->matrix_coefficients =
1629 gst_video_color_matrix_to_iso (colorimetry->matrix);
1631 properties->color_range = from_GstVideoColorRange (colorimetry->range);
1636 gst_vaapi_filter_fill_color_standards (GstVaapiFilter * filter,
1637 VAProcPipelineParameterBuffer * pipeline_param)
1639 #if VA_CHECK_VERSION(1,2,0)
1640 fill_color_standard (&filter->input_colorimetry,
1641 &pipeline_param->surface_color_standard,
1642 &pipeline_param->input_color_properties);
1644 fill_color_standard (&filter->output_colorimetry,
1645 &pipeline_param->output_color_standard,
1646 &pipeline_param->output_color_properties);
1648 pipeline_param->surface_color_standard = VAProcColorStandardNone;
1649 pipeline_param->output_color_standard = VAProcColorStandardNone;
1654 * gst_vaapi_filter_process:
1655 * @filter: a #GstVaapiFilter
1656 * @src_surface: the source @GstVaapiSurface
1657 * @dst_surface: the destination @GstVaapiSurface
1658 * @flags: #GstVaapiSurfaceRenderFlags that apply to @src_surface
1660 * Applies the operations currently defined in the @filter to
1661 * @src_surface and return the output in @dst_surface. The order of
1662 * operations is determined in a way that suits best the underlying
1663 * hardware. i.e. the only guarantee held is the generated outcome,
1664 * not any specific order of operations.
1666 * Return value: a #GstVaapiFilterStatus
1668 static GstVaapiFilterStatus
1669 gst_vaapi_filter_process_unlocked (GstVaapiFilter * filter,
1670 GstVaapiSurface * src_surface, GstVaapiSurface * dst_surface, guint flags)
1672 VAProcPipelineParameterBuffer *pipeline_param = NULL;
1673 VABufferID pipeline_param_buf_id = VA_INVALID_ID;
1674 VABufferID filters[N_PROPERTIES];
1675 VAProcPipelineCaps pipeline_caps;
1676 guint i, num_filters = 0;
1678 VARectangle src_rect, dst_rect;
1679 guint va_mirror = 0, va_rotation = 0;
1681 if (!ensure_operations (filter))
1682 return GST_VAAPI_FILTER_STATUS_ERROR_ALLOCATION_FAILED;
1684 /* Build surface region (source) */
1685 if (filter->use_crop_rect) {
1686 const GstVaapiRectangle *const crop_rect = &filter->crop_rect;
1688 if ((crop_rect->x + crop_rect->width >
1689 GST_VAAPI_SURFACE_WIDTH (src_surface)) ||
1690 (crop_rect->y + crop_rect->height >
1691 GST_VAAPI_SURFACE_HEIGHT (src_surface)))
1694 src_rect.x = crop_rect->x;
1695 src_rect.y = crop_rect->y;
1696 src_rect.width = crop_rect->width;
1697 src_rect.height = crop_rect->height;
1701 src_rect.width = GST_VAAPI_SURFACE_WIDTH (src_surface);
1702 src_rect.height = GST_VAAPI_SURFACE_HEIGHT (src_surface);
1705 /* Build output region (target) */
1706 if (filter->use_target_rect) {
1707 const GstVaapiRectangle *const target_rect = &filter->target_rect;
1709 if ((target_rect->x + target_rect->width >
1710 GST_VAAPI_SURFACE_WIDTH (dst_surface)) ||
1711 (target_rect->y + target_rect->height >
1712 GST_VAAPI_SURFACE_HEIGHT (dst_surface)))
1715 dst_rect.x = target_rect->x;
1716 dst_rect.y = target_rect->y;
1717 dst_rect.width = target_rect->width;
1718 dst_rect.height = target_rect->height;
1722 dst_rect.width = GST_VAAPI_SURFACE_WIDTH (dst_surface);
1723 dst_rect.height = GST_VAAPI_SURFACE_HEIGHT (dst_surface);
1726 for (i = 0, num_filters = 0; i < filter->operations->len; i++) {
1727 GstVaapiFilterOpData *const op_data =
1728 g_ptr_array_index (filter->operations, i);
1729 if (!op_data->is_enabled)
1731 if (op_data->va_buffer == VA_INVALID_ID) {
1732 GST_ERROR ("invalid VA buffer for operation %s",
1733 g_param_spec_get_name (op_data->pspec));
1736 filters[num_filters++] = op_data->va_buffer;
1739 /* Validate pipeline caps */
1740 va_status = vaQueryVideoProcPipelineCaps (filter->va_display,
1741 filter->va_context, filters, num_filters, &pipeline_caps);
1742 if (!vaapi_check_status (va_status, "vaQueryVideoProcPipelineCaps()"))
1745 if (!vaapi_create_buffer (filter->va_display, filter->va_context,
1746 VAProcPipelineParameterBufferType, sizeof (*pipeline_param),
1747 NULL, &pipeline_param_buf_id, (gpointer *) & pipeline_param))
1750 memset (pipeline_param, 0, sizeof (*pipeline_param));
1751 pipeline_param->surface = GST_VAAPI_SURFACE_ID (src_surface);
1752 pipeline_param->surface_region = &src_rect;
1754 gst_vaapi_filter_fill_color_standards (filter, pipeline_param);
1756 pipeline_param->output_region = &dst_rect;
1757 pipeline_param->output_background_color = 0xff000000;
1758 pipeline_param->filter_flags = from_GstVaapiSurfaceRenderFlags (flags) |
1759 from_GstVaapiScaleMethod (filter->scale_method);
1760 pipeline_param->filters = filters;
1761 pipeline_param->num_filters = num_filters;
1763 from_GstVideoOrientationMethod (filter->video_direction, &va_mirror,
1766 #if VA_CHECK_VERSION(1,1,0)
1767 pipeline_param->mirror_state = va_mirror;
1768 pipeline_param->rotation_state = va_rotation;
1771 // Reference frames for advanced deinterlacing
1772 if (filter->forward_references->len > 0) {
1773 pipeline_param->forward_references = (VASurfaceID *)
1774 filter->forward_references->data;
1775 pipeline_param->num_forward_references =
1776 MIN (filter->forward_references->len,
1777 pipeline_caps.num_forward_references);
1779 pipeline_param->forward_references = NULL;
1780 pipeline_param->num_forward_references = 0;
1783 if (filter->backward_references->len > 0) {
1784 pipeline_param->backward_references = (VASurfaceID *)
1785 filter->backward_references->data;
1786 pipeline_param->num_backward_references =
1787 MIN (filter->backward_references->len,
1788 pipeline_caps.num_backward_references);
1790 pipeline_param->backward_references = NULL;
1791 pipeline_param->num_backward_references = 0;
1794 vaapi_unmap_buffer (filter->va_display, pipeline_param_buf_id, NULL);
1796 va_status = vaBeginPicture (filter->va_display, filter->va_context,
1797 GST_VAAPI_SURFACE_ID (dst_surface));
1798 if (!vaapi_check_status (va_status, "vaBeginPicture()"))
1801 va_status = vaRenderPicture (filter->va_display, filter->va_context,
1802 &pipeline_param_buf_id, 1);
1803 if (!vaapi_check_status (va_status, "vaRenderPicture()"))
1806 va_status = vaEndPicture (filter->va_display, filter->va_context);
1807 if (!vaapi_check_status (va_status, "vaEndPicture()"))
1810 deint_refs_clear_all (filter);
1811 vaapi_destroy_buffer (filter->va_display, &pipeline_param_buf_id);
1812 return GST_VAAPI_FILTER_STATUS_SUCCESS;
1817 deint_refs_clear_all (filter);
1818 vaapi_destroy_buffer (filter->va_display, &pipeline_param_buf_id);
1819 return GST_VAAPI_FILTER_STATUS_ERROR_OPERATION_FAILED;
1823 GstVaapiFilterStatus
1824 gst_vaapi_filter_process (GstVaapiFilter * filter,
1825 GstVaapiSurface * src_surface, GstVaapiSurface * dst_surface, guint flags)
1827 GstVaapiFilterStatus status;
1829 g_return_val_if_fail (filter != NULL,
1830 GST_VAAPI_FILTER_STATUS_ERROR_INVALID_PARAMETER);
1831 g_return_val_if_fail (src_surface != NULL,
1832 GST_VAAPI_FILTER_STATUS_ERROR_INVALID_PARAMETER);
1833 g_return_val_if_fail (dst_surface != NULL,
1834 GST_VAAPI_FILTER_STATUS_ERROR_INVALID_PARAMETER);
1836 GST_VAAPI_DISPLAY_LOCK (filter->display);
1837 status = gst_vaapi_filter_process_unlocked (filter,
1838 src_surface, dst_surface, flags);
1839 GST_VAAPI_DISPLAY_UNLOCK (filter->display);
1844 * gst_vaapi_filter_get_formats:
1845 * @filter: a #GstVaapiFilter
1847 * Determines the set of supported source or target formats for video
1848 * processing. The caller owns an extra reference to the resulting
1849 * array of #GstVideoFormat elements, so it shall be released with
1850 * g_array_unref() after usage.
1852 * Return value: the set of supported target formats for video processing.
1855 gst_vaapi_filter_get_formats (GstVaapiFilter * filter)
1857 g_return_val_if_fail (filter != NULL, NULL);
1859 if (!ensure_attributes (filter))
1861 if (filter->attribs->formats)
1862 return g_array_ref (filter->attribs->formats);
1867 * gst_vaapi_filter_set_format:
1868 * @filter: a #GstVaapiFilter
1869 * @format: the target surface format
1871 * Sets the desired pixel format of the resulting video processing
1874 * If @format is #GST_VIDEO_FORMAT_UNKNOWN, the filter will assume iso
1875 * format conversion, i.e. no color conversion at all and the target
1876 * surface format shall match the source surface format.
1878 * If @format is #GST_VIDEO_FORMAT_ENCODED, the filter will use the pixel
1879 * format of the target surface passed to gst_vaapi_filter_process().
1881 * Return value: %TRUE if the color conversion to the specified @format
1882 * may be supported, %FALSE otherwise.
1885 gst_vaapi_filter_set_format (GstVaapiFilter * filter, GstVideoFormat format)
1887 g_return_val_if_fail (filter != NULL, FALSE);
1889 if (!ensure_attributes (filter))
1892 if (!is_special_format (format) && !find_format (filter, format))
1895 filter->format = format;
1900 * gst_vaapi_filter_append_caps:
1901 * @filter: a #GstVaapiFilter
1902 * @structure: a #GstStructure from #GstCaps
1904 * Extracts the config's surface attributes, from @filter's context,
1905 * and transforms it into a caps formats and appended them into
1908 * Returns: %TRUE if the capabilities could be extracted and appended
1909 * into @structure; otherwise %FALSE
1912 gst_vaapi_filter_append_caps (GstVaapiFilter * filter, GstStructure * structure)
1914 GstVaapiConfigSurfaceAttributes *attribs;
1916 g_return_val_if_fail (filter != NULL, FALSE);
1917 g_return_val_if_fail (structure != NULL, FALSE);
1919 if (!ensure_attributes (filter))
1922 attribs = filter->attribs;
1924 if (attribs->min_width >= attribs->max_width ||
1925 attribs->min_height >= attribs->max_height)
1928 gst_structure_set (structure, "width", GST_TYPE_INT_RANGE, attribs->min_width,
1929 attribs->max_width, "height", GST_TYPE_INT_RANGE, attribs->min_height,
1930 attribs->max_height, NULL);
1937 * gst_vaapi_filter_get_memory_types:
1938 * @filter: a #GstVaapiFilter
1940 * Gets the surface's memory types available in @filter's context.
1942 * Returns: surface's memory types available in @filter context.
1945 gst_vaapi_filter_get_memory_types (GstVaapiFilter * filter)
1947 g_return_val_if_fail (filter != NULL, FALSE);
1949 if (!ensure_attributes (filter))
1951 return filter->attribs->mem_types;
1955 * gst_vaapi_filter_set_cropping_rectangle:
1956 * @filter: a #GstVaapiFilter
1957 * @rect: the cropping region
1959 * Sets the source surface cropping rectangle to use during the video
1960 * processing. If @rect is %NULL, the whole source surface will be used.
1962 * Return value: %TRUE if the operation is supported, %FALSE otherwise.
1965 gst_vaapi_filter_set_cropping_rectangle (GstVaapiFilter * filter,
1966 const GstVaapiRectangle * rect)
1968 g_return_val_if_fail (filter != NULL, FALSE);
1970 filter->use_crop_rect = rect != NULL;
1971 if (filter->use_crop_rect)
1972 filter->crop_rect = *rect;
1977 * gst_vaapi_filter_set_target_rectangle:
1978 * @filter: a #GstVaapiFilter
1979 * @rect: the target render region
1981 * Sets the region within the target surface where the source surface
1982 * would be rendered. i.e. where the hardware accelerator would emit
1983 * the outcome of video processing. If @rect is %NULL, the whole
1984 * source surface will be used.
1986 * Return value: %TRUE if the operation is supported, %FALSE otherwise.
1989 gst_vaapi_filter_set_target_rectangle (GstVaapiFilter * filter,
1990 const GstVaapiRectangle * rect)
1992 g_return_val_if_fail (filter != NULL, FALSE);
1994 filter->use_target_rect = rect != NULL;
1995 if (filter->use_target_rect)
1996 filter->target_rect = *rect;
2001 * gst_vaapi_filter_set_denoising_level:
2002 * @filter: a #GstVaapiFilter
2003 * @level: the level of noise reduction to apply
2005 * Sets the noise reduction level to apply. If @level is 0.0f, this
2006 * corresponds to disabling the noise reduction algorithm.
2008 * Return value: %TRUE if the operation is supported, %FALSE otherwise.
2011 gst_vaapi_filter_set_denoising_level (GstVaapiFilter * filter, gfloat level)
2013 g_return_val_if_fail (filter != NULL, FALSE);
2015 return op_set_generic (filter,
2016 find_operation (filter, GST_VAAPI_FILTER_OP_DENOISE), level);
2020 * gst_vaapi_filter_set_sharpening_level:
2021 * @filter: a #GstVaapiFilter
2022 * @level: the sharpening factor
2024 * Enables noise reduction with the specified factor.
2026 * Return value: %TRUE if the operation is supported, %FALSE otherwise.
2029 gst_vaapi_filter_set_sharpening_level (GstVaapiFilter * filter, gfloat level)
2031 g_return_val_if_fail (filter != NULL, FALSE);
2033 return op_set_generic (filter,
2034 find_operation (filter, GST_VAAPI_FILTER_OP_SHARPEN), level);
2038 * gst_vaapi_filter_set_hue:
2039 * @filter: a #GstVaapiFilter
2040 * @value: the color hue value
2042 * Enables color hue adjustment to the specified value.
2044 * Return value: %TRUE if the operation is supported, %FALSE otherwise.
2047 gst_vaapi_filter_set_hue (GstVaapiFilter * filter, gfloat value)
2049 g_return_val_if_fail (filter != NULL, FALSE);
2051 return op_set_color_balance (filter,
2052 find_operation (filter, GST_VAAPI_FILTER_OP_HUE), value);
2056 * gst_vaapi_filter_set_saturation:
2057 * @filter: a #GstVaapiFilter
2058 * @value: the color saturation value
2060 * Enables color saturation adjustment to the specified value.
2062 * Return value: %TRUE if the operation is supported, %FALSE otherwise.
2065 gst_vaapi_filter_set_saturation (GstVaapiFilter * filter, gfloat value)
2067 g_return_val_if_fail (filter != NULL, FALSE);
2069 return op_set_color_balance (filter,
2070 find_operation (filter, GST_VAAPI_FILTER_OP_SATURATION), value);
2074 * gst_vaapi_filter_set_brightness:
2075 * @filter: a #GstVaapiFilter
2076 * @value: the color brightness value
2078 * Enables color brightness adjustment to the specified value.
2080 * Return value: %TRUE if the operation is supported, %FALSE otherwise.
2083 gst_vaapi_filter_set_brightness (GstVaapiFilter * filter, gfloat value)
2085 g_return_val_if_fail (filter != NULL, FALSE);
2087 return op_set_color_balance (filter,
2088 find_operation (filter, GST_VAAPI_FILTER_OP_BRIGHTNESS), value);
2092 * gst_vaapi_filter_set_contrast:
2093 * @filter: a #GstVaapiFilter
2094 * @value: the color contrast value
2096 * Enables color contrast adjustment to the specified value.
2098 * Return value: %TRUE if the operation is supported, %FALSE otherwise.
2101 gst_vaapi_filter_set_contrast (GstVaapiFilter * filter, gfloat value)
2103 g_return_val_if_fail (filter != NULL, FALSE);
2105 return op_set_color_balance (filter,
2106 find_operation (filter, GST_VAAPI_FILTER_OP_CONTRAST), value);
2110 * gst_vaapi_filter_set_deinterlacing:
2111 * @filter: a #GstVaapiFilter
2112 * @method: the deinterlacing algorithm (see #GstVaapiDeinterlaceMethod)
2113 * @flags: the additional flags
2115 * Applies deinterlacing to the video processing pipeline. If @method
2116 * is not @GST_VAAPI_DEINTERLACE_METHOD_NONE, then @flags could
2117 * represent the initial picture structure of the source frame.
2119 * Return value: %TRUE if the operation is supported, %FALSE otherwise.
2122 gst_vaapi_filter_set_deinterlacing (GstVaapiFilter * filter,
2123 GstVaapiDeinterlaceMethod method, guint flags)
2125 g_return_val_if_fail (filter != NULL, FALSE);
2127 return op_set_deinterlace (filter,
2128 find_operation (filter, GST_VAAPI_FILTER_OP_DEINTERLACING), method,
2133 * gst_vaapi_filter_set_deinterlacing_references:
2134 * @filter: a #GstVaapiFilter
2135 * @forward_references: the set of #GstVaapiSurface objects used as
2136 * forward references
2137 * @num_forward_references: the number of elements in the
2138 * @forward_references array
2139 * @backward_references: the set of #GstVaapiSurface objects used as
2140 * backward references
2141 * @num_backward_references: the number of elements in the
2142 * @backward_references array
2144 * Specifies the list of surfaces used for forward or backward reference in
2145 * advanced deinterlacing mode. The caller is responsible for maintaining
2146 * the associated surfaces live until gst_vaapi_filter_process() completes.
2147 * e.g. by holding an extra reference to the associated #GstVaapiSurfaceProxy.
2149 * Temporal ordering is maintained as follows: the shorter index in
2150 * either array is, the closest the matching surface is relatively to
2151 * the current source surface to process. e.g. surface in
2152 * @forward_references array index 0 represents the immediately
2153 * preceding surface in display order, surface at index 1 is the one
2154 * preceding surface at index 0, etc.
2156 * The video processing filter will only use the recommended number of
2157 * surfaces for backward and forward references.
2159 * Note: the supplied lists of reference surfaces are not sticky. This
2160 * means that they are only valid for the next gst_vaapi_filter_process()
2161 * call, and thus needs to be submitted again for subsequent calls.
2163 * Return value: %TRUE if the operation is supported, %FALSE otherwise.
2166 gst_vaapi_filter_set_deinterlacing_references (GstVaapiFilter * filter,
2167 GstVaapiSurface ** forward_references, guint num_forward_references,
2168 GstVaapiSurface ** backward_references, guint num_backward_references)
2170 g_return_val_if_fail (filter != NULL, FALSE);
2172 deint_refs_clear_all (filter);
2174 if (!deint_refs_set (filter->forward_references, forward_references,
2175 num_forward_references))
2178 if (!deint_refs_set (filter->backward_references, backward_references,
2179 num_backward_references))
2185 * gst_vaapi_filter_set_scaling:
2186 * @filter: a #GstVaapiFilter
2187 * @method: the scaling algorithm (see #GstVaapiScaleMethod)
2189 * Applies scaling algorithm to the video processing pipeline.
2191 * Return value: %TRUE if the operation is supported, %FALSE otherwise.
2194 gst_vaapi_filter_set_scaling (GstVaapiFilter * filter,
2195 GstVaapiScaleMethod method)
2197 g_return_val_if_fail (filter != NULL, FALSE);
2199 filter->scale_method = method;
2203 #ifndef GST_REMOVE_DEPRECATED
2205 * gst_vaapi_filter_set_skintone:
2206 * @filter: a #GstVaapiFilter
2207 * @enhance: %TRUE if enable the skin tone enhancement algorithm
2209 * Applies the skin tone enhancement algorithm.
2211 * Return value: %TRUE if the operation is supported, %FALSE
2215 gst_vaapi_filter_set_skintone (GstVaapiFilter * filter, gboolean enhance)
2217 g_return_val_if_fail (filter != NULL, FALSE);
2219 return op_set_skintone (filter,
2220 find_operation (filter, GST_VAAPI_FILTER_OP_SKINTONE), enhance);
2225 * gst_vaapi_filter_set_skintone_level:
2226 * @filter: a #GstVaapiFilter
2227 * @value: the value if enable the skin tone enhancement algorithm
2229 * Applies the skin tone enhancement algorithm with specifled value.
2231 * Return value: %TRUE if the operation is supported, %FALSE
2235 gst_vaapi_filter_set_skintone_level (GstVaapiFilter * filter, guint value)
2237 g_return_val_if_fail (filter != NULL, FALSE);
2239 return op_set_skintone_level (filter,
2240 find_operation (filter, GST_VAAPI_FILTER_OP_SKINTONE_LEVEL), value);
2244 * gst_vaapi_filter_set_video_direction:
2245 * @filter: a #GstVaapiFilter
2246 * @method: the video direction (see #GstVideoOrientationMethod)
2248 * Applies mirror/rotation to the video processing pipeline.
2250 * Return value: %TRUE if the operation is supported, %FALSE otherwise.
2253 gst_vaapi_filter_set_video_direction (GstVaapiFilter * filter,
2254 GstVideoOrientationMethod method)
2256 g_return_val_if_fail (filter != NULL, FALSE);
2258 #if VA_CHECK_VERSION(1,1,0)
2260 guint32 va_mirror = VA_MIRROR_NONE;
2261 guint32 va_rotation = VA_ROTATION_NONE;
2263 from_GstVideoOrientationMethod (method, &va_mirror, &va_rotation);
2265 if (va_mirror != VA_MIRROR_NONE && !(filter->mirror_flags & va_mirror))
2268 if (va_rotation != VA_ROTATION_NONE
2269 && !(filter->rotation_flags & (1 << va_rotation)))
2276 filter->video_direction = method;
2281 * gst_vaapi_filter_get_video_direction:
2282 * @filter: a #GstVaapiFilter
2284 * Return value: the currently applied video direction (see #GstVideoOrientationMethod)
2286 GstVideoOrientationMethod
2287 gst_vaapi_filter_get_video_direction (GstVaapiFilter * filter)
2289 g_return_val_if_fail (filter != NULL, GST_VIDEO_ORIENTATION_IDENTITY);
2290 return filter->video_direction;
2294 gst_vaapi_filter_get_denoising_level_default (GstVaapiFilter * filter)
2296 OP_RET_DEFAULT_VALUE (float, filter, GST_VAAPI_FILTER_OP_DENOISE);
2300 gst_vaapi_filter_get_sharpening_level_default (GstVaapiFilter * filter)
2302 OP_RET_DEFAULT_VALUE (float, filter, GST_VAAPI_FILTER_OP_SHARPEN);
2306 gst_vaapi_filter_get_hue_default (GstVaapiFilter * filter)
2308 OP_RET_DEFAULT_VALUE (float, filter, GST_VAAPI_FILTER_OP_HUE);
2312 gst_vaapi_filter_get_saturation_default (GstVaapiFilter * filter)
2314 OP_RET_DEFAULT_VALUE (float, filter, GST_VAAPI_FILTER_OP_SATURATION);
2318 gst_vaapi_filter_get_brightness_default (GstVaapiFilter * filter)
2320 OP_RET_DEFAULT_VALUE (float, filter, GST_VAAPI_FILTER_OP_BRIGHTNESS);
2324 gst_vaapi_filter_get_contrast_default (GstVaapiFilter * filter)
2326 OP_RET_DEFAULT_VALUE (float, filter, GST_VAAPI_FILTER_OP_CONTRAST);
2330 gst_vaapi_filter_get_scaling_default (GstVaapiFilter * filter)
2332 OP_RET_DEFAULT_VALUE (enum, filter, GST_VAAPI_FILTER_OP_SCALING);
2335 #ifndef GST_REMOVE_DEPRECATED
2337 gst_vaapi_filter_get_skintone_default (GstVaapiFilter * filter)
2339 OP_RET_DEFAULT_VALUE (boolean, filter, GST_VAAPI_FILTER_OP_SKINTONE);
2344 gst_vaapi_filter_get_skintone_level_default (GstVaapiFilter * filter)
2346 OP_RET_DEFAULT_VALUE (uint, filter, GST_VAAPI_FILTER_OP_SKINTONE_LEVEL);
2349 GstVideoOrientationMethod
2350 gst_vaapi_filter_get_video_direction_default (GstVaapiFilter * filter)
2352 OP_RET_DEFAULT_VALUE (enum, filter, GST_VAAPI_FILTER_OP_VIDEO_DIRECTION);
2356 gst_vaapi_filter_set_colorimetry_unlocked (GstVaapiFilter * filter,
2357 GstVideoColorimetry * input, GstVideoColorimetry * output)
2359 gchar *in_color, *out_color;
2362 filter->input_colorimetry = *input;
2364 gst_video_colorimetry_from_string (&filter->input_colorimetry, NULL);
2367 filter->output_colorimetry = *output;
2369 gst_video_colorimetry_from_string (&filter->output_colorimetry, NULL);
2371 in_color = gst_video_colorimetry_to_string (&filter->input_colorimetry);
2372 GST_DEBUG_OBJECT (filter, " input colorimetry '%s'", in_color);
2374 out_color = gst_video_colorimetry_to_string (&filter->output_colorimetry);
2375 GST_DEBUG_OBJECT (filter, "output colorimetry '%s'", out_color);
2377 if (!gst_vaapi_display_has_driver_quirks (filter->display,
2378 GST_VAAPI_DRIVER_QUIRK_NO_CHECK_VPP_COLOR_STD)) {
2379 VAProcPipelineCaps pipeline_caps = { 0, };
2380 VAProcColorStandardType type;
2383 VAStatus va_status = vaQueryVideoProcPipelineCaps (filter->va_display,
2384 filter->va_context, NULL, 0, &pipeline_caps);
2386 if (!vaapi_check_status (va_status, "vaQueryVideoProcPipelineCaps()"))
2389 type = from_GstVideoColorimetry (&filter->input_colorimetry);
2390 for (i = 0; i < pipeline_caps.num_input_color_standards; i++)
2391 if (type == pipeline_caps.input_color_standards[i])
2393 if ((i == pipeline_caps.num_input_color_standards)
2394 && (type != VAProcColorStandardNone))
2395 GST_WARNING_OBJECT (filter,
2396 "driver does not support '%s' input colorimetry."
2397 " vpp may fail or produce unexpected results.", in_color);
2399 type = from_GstVideoColorimetry (&filter->output_colorimetry);
2400 for (i = 0; i < pipeline_caps.num_output_color_standards; i++)
2401 if (type == pipeline_caps.output_color_standards[i])
2403 if ((i == pipeline_caps.num_output_color_standards)
2404 && (type != VAProcColorStandardNone))
2405 GST_WARNING_OBJECT (filter,
2406 "driver does not support '%s' output colorimetry."
2407 " vpp may fail or produce unexpected results.", out_color);
2409 GST_WARNING_OBJECT (filter,
2410 "driver does not report the supported input/output colorimetry."
2411 " vpp may fail or produce unexpected results.");
2421 gst_vaapi_filter_set_colorimetry (GstVaapiFilter * filter,
2422 GstVideoColorimetry * input, GstVideoColorimetry * output)
2426 g_return_val_if_fail (filter != NULL, FALSE);
2428 GST_VAAPI_DISPLAY_LOCK (filter->display);
2429 result = gst_vaapi_filter_set_colorimetry_unlocked (filter, input, output);
2430 GST_VAAPI_DISPLAY_UNLOCK (filter->display);
2436 * gst_vaapi_filter_set_hdr_tone_map:
2437 * @filter: a #GstVaapiFilter
2438 * @value: %TRUE to enable hdr tone map algorithm
2440 * Applies HDR tone mapping algorithm.
2442 * Return value: %TRUE if the operation is supported, %FALSE otherwise.
2445 gst_vaapi_filter_set_hdr_tone_map (GstVaapiFilter * filter, gboolean value)
2447 g_return_val_if_fail (filter != NULL, FALSE);
2449 return op_set_hdr_tone_map (filter,
2450 find_operation (filter, GST_VAAPI_FILTER_OP_HDR_TONE_MAP), value);
2454 gst_vaapi_filter_set_hdr_tone_map_meta_unlocked (GstVaapiFilter * filter,
2455 GstVideoMasteringDisplayInfo * minfo, GstVideoContentLightLevel * linfo)
2457 #if VA_CHECK_VERSION(1,4,0)
2458 GstVaapiFilterOpData *op_data;
2459 VAProcFilterParameterBufferHDRToneMapping *buf;
2460 VAHdrMetaDataHDR10 *meta = &filter->hdr_meta;
2462 op_data = find_operation (filter, GST_VAAPI_FILTER_OP_HDR_TONE_MAP);
2467 meta->display_primaries_x[0] = minfo->display_primaries[1].x;
2468 meta->display_primaries_x[1] = minfo->display_primaries[2].x;
2469 meta->display_primaries_x[2] = minfo->display_primaries[0].x;
2471 meta->display_primaries_y[0] = minfo->display_primaries[1].y;
2472 meta->display_primaries_y[1] = minfo->display_primaries[2].y;
2473 meta->display_primaries_y[2] = minfo->display_primaries[0].y;
2475 meta->white_point_x = minfo->white_point.x;
2476 meta->white_point_y = minfo->white_point.y;
2478 meta->max_display_mastering_luminance =
2479 minfo->max_display_mastering_luminance;
2480 meta->min_display_mastering_luminance =
2481 minfo->min_display_mastering_luminance;
2483 meta->max_content_light_level = linfo->max_content_light_level;
2484 meta->max_pic_average_light_level = linfo->max_frame_average_light_level;
2486 buf = vaapi_map_buffer (filter->va_display, op_data->va_buffer);
2490 buf->type = op_data->va_type;
2491 buf->data.metadata_type = op_data->va_subtype;
2492 buf->data.metadata = meta;
2493 buf->data.metadata_size = sizeof (meta);
2495 vaapi_unmap_buffer (filter->va_display, op_data->va_buffer, NULL);
2504 * gst_vaapi_filter_set_hdr_tone_map_meta:
2505 * @filter: a #GstVaapiFilter
2506 * @minfo: a #GstVideoMasteringDisplayInfo
2507 * @linfo: a #GstVideoContentLightLevel
2509 * Sets the input HDR meta data used for tone mapping.
2511 * Return value: %TRUE if the operation is supported, %FALSE otherwise.
2514 gst_vaapi_filter_set_hdr_tone_map_meta (GstVaapiFilter * filter,
2515 GstVideoMasteringDisplayInfo * minfo, GstVideoContentLightLevel * linfo)
2517 gboolean status = FALSE;
2519 g_return_val_if_fail (filter != NULL, FALSE);
2520 g_return_val_if_fail (minfo != NULL, FALSE);
2521 g_return_val_if_fail (linfo != NULL, FALSE);
2523 GST_VAAPI_DISPLAY_LOCK (filter->display);
2525 gst_vaapi_filter_set_hdr_tone_map_meta_unlocked (filter, minfo, linfo);
2526 GST_VAAPI_DISPLAY_UNLOCK (filter->display);