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
24 #include "gstvaapicompat.h"
25 #include "gstvaapifilter.h"
26 #include "gstvaapiutils.h"
27 #include "gstvaapivalue.h"
28 #include "gstvaapiminiobject.h"
29 #include "gstvaapidisplay_priv.h"
30 #include "gstvaapisurface_priv.h"
31 #include "gstvaapiutils_core.h"
33 #define GST_VAAPI_FILTER_CAST(obj) \
34 ((GstVaapiFilter *)(obj))
36 typedef struct _GstVaapiFilterOpData GstVaapiFilterOpData;
37 struct _GstVaapiFilterOpData
52 struct _GstVaapiFilter
55 GstObject parent_instance;
57 GstVaapiDisplay *display;
60 VAContextID va_context;
61 GPtrArray *operations;
62 GstVideoFormat format;
63 GstVaapiScaleMethod scale_method;
64 GstVideoOrientationMethod video_direction;
65 GstVaapiConfigSurfaceAttributes *attribs;
66 GArray *forward_references;
67 GArray *backward_references;
68 GstVaapiRectangle crop_rect;
69 GstVaapiRectangle target_rect;
70 guint use_crop_rect:1;
71 guint use_target_rect:1;
73 guint32 rotation_flags;
75 GstVideoColorimetry input_colorimetry;
76 GstVideoColorimetry output_colorimetry;
78 #if VA_CHECK_VERSION(1,4,0)
79 VAHdrMetaDataHDR10 hdr_meta;
83 typedef struct _GstVaapiFilterClass GstVaapiFilterClass;
84 struct _GstVaapiFilterClass
87 GstObjectClass parent_class;
90 /* Debug category for VaapiFilter */
91 GST_DEBUG_CATEGORY (gst_debug_vaapi_filter);
92 #define GST_CAT_DEFAULT gst_debug_vaapi_filter
95 GST_DEBUG_CATEGORY_INIT (gst_debug_vaapi_filter, "vaapifilter", 0, \
98 G_DEFINE_TYPE_WITH_CODE (GstVaapiFilter, gst_vaapi_filter, GST_TYPE_OBJECT,
101 /* ------------------------------------------------------------------------- */
102 /* --- VPP Types --- */
103 /* ------------------------------------------------------------------------- */
106 gst_vaapi_scale_method_get_type (void)
108 static gsize g_type = 0;
110 static const GEnumValue enum_values[] = {
111 {GST_VAAPI_SCALE_METHOD_DEFAULT,
112 "Default scaling mode", "default"},
113 {GST_VAAPI_SCALE_METHOD_FAST,
114 "Fast scaling mode", "fast"},
115 {GST_VAAPI_SCALE_METHOD_HQ,
116 "High quality scaling mode", "hq"},
120 if (g_once_init_enter (&g_type)) {
122 g_enum_register_static ("GstVaapiScaleMethod", enum_values);
123 g_once_init_leave (&g_type, type);
125 gst_type_mark_as_plugin_api (type, 0);
131 gst_vaapi_deinterlace_method_get_type (void)
133 static gsize g_type = 0;
135 static const GEnumValue enum_values[] = {
136 {GST_VAAPI_DEINTERLACE_METHOD_NONE,
137 "Disable deinterlacing", "none"},
138 {GST_VAAPI_DEINTERLACE_METHOD_BOB,
139 "Bob deinterlacing", "bob"},
140 {GST_VAAPI_DEINTERLACE_METHOD_WEAVE,
141 "Weave deinterlacing", "weave"},
142 {GST_VAAPI_DEINTERLACE_METHOD_MOTION_ADAPTIVE,
143 "Motion adaptive deinterlacing", "motion-adaptive"},
144 {GST_VAAPI_DEINTERLACE_METHOD_MOTION_COMPENSATED,
145 "Motion compensated deinterlacing", "motion-compensated"},
149 if (g_once_init_enter (&g_type)) {
151 g_enum_register_static ("GstVaapiDeinterlaceMethod", enum_values);
152 gst_type_mark_as_plugin_api (type, 0);
153 g_once_init_leave (&g_type, type);
159 gst_vaapi_deinterlace_flags_get_type (void)
161 static gsize g_type = 0;
163 static const GEnumValue enum_values[] = {
164 {GST_VAAPI_DEINTERLACE_FLAG_TFF,
165 "Top-field first", "top-field-first"},
166 {GST_VAAPI_DEINTERLACE_FLAG_ONEFIELD,
167 "One field", "one-field"},
168 {GST_VAAPI_DEINTERLACE_FLAG_TOPFIELD,
169 "Top field", "top-field"},
173 if (g_once_init_enter (&g_type)) {
175 g_enum_register_static ("GstVaapiDeinterlaceFlags", enum_values);
176 gst_type_mark_as_plugin_api (type, 0);
177 g_once_init_leave (&g_type, type);
182 /* ------------------------------------------------------------------------- */
183 /* --- VPP Helpers --- */
184 /* ------------------------------------------------------------------------- */
186 static VAProcFilterType *
187 vpp_get_filters_unlocked (GstVaapiFilter * filter, guint * num_filters_ptr)
189 VAProcFilterType *filters = NULL;
190 guint num_filters = 0;
193 num_filters = VAProcFilterCount;
194 filters = g_malloc_n (num_filters, sizeof (*filters));
198 va_status = vaQueryVideoProcFilters (filter->va_display, filter->va_context,
199 filters, &num_filters);
201 // Try to reallocate to the expected number of filters
202 if (va_status == VA_STATUS_ERROR_MAX_NUM_EXCEEDED) {
203 VAProcFilterType *const new_filters =
204 g_try_realloc_n (filters, num_filters, sizeof (*new_filters));
207 filters = new_filters;
209 va_status = vaQueryVideoProcFilters (filter->va_display,
210 filter->va_context, filters, &num_filters);
212 if (!vaapi_check_status (va_status, "vaQueryVideoProcFilters()"))
215 *num_filters_ptr = num_filters;
226 static VAProcFilterType *
227 vpp_get_filters (GstVaapiFilter * filter, guint * num_filters_ptr)
229 VAProcFilterType *filters;
231 GST_VAAPI_DISPLAY_LOCK (filter->display);
232 filters = vpp_get_filters_unlocked (filter, num_filters_ptr);
233 GST_VAAPI_DISPLAY_UNLOCK (filter->display);
238 vpp_get_filter_caps_unlocked (GstVaapiFilter * filter, VAProcFilterType type,
239 guint cap_size, guint * num_caps_ptr)
245 caps = g_malloc (cap_size);
249 va_status = vaQueryVideoProcFilterCaps (filter->va_display,
250 filter->va_context, type, caps, &num_caps);
252 // Try to reallocate to the expected number of filters
253 if (va_status == VA_STATUS_ERROR_MAX_NUM_EXCEEDED) {
254 gpointer const new_caps = g_try_realloc_n (caps, num_caps, cap_size);
259 va_status = vaQueryVideoProcFilterCaps (filter->va_display,
260 filter->va_context, type, caps, &num_caps);
262 if (!vaapi_check_status (va_status, "vaQueryVideoProcFilterCaps()"))
265 *num_caps_ptr = num_caps;
277 vpp_get_filter_caps (GstVaapiFilter * filter, VAProcFilterType type,
278 guint cap_size, guint * num_caps_ptr)
282 GST_VAAPI_DISPLAY_LOCK (filter->display);
283 caps = vpp_get_filter_caps_unlocked (filter, type, cap_size, num_caps_ptr);
284 GST_VAAPI_DISPLAY_UNLOCK (filter->display);
289 vpp_get_pipeline_caps_unlocked (GstVaapiFilter * filter)
291 #if VA_CHECK_VERSION(1,1,0)
292 VAProcPipelineCaps pipeline_caps = { 0, };
294 VAStatus va_status = vaQueryVideoProcPipelineCaps (filter->va_display,
295 filter->va_context, NULL, 0, &pipeline_caps);
297 if (vaapi_check_status (va_status, "vaQueryVideoProcPipelineCaps()")) {
298 filter->mirror_flags = pipeline_caps.mirror_flags;
299 filter->rotation_flags = pipeline_caps.rotation_flags;
304 filter->mirror_flags = 0;
305 filter->rotation_flags = 0;
309 vpp_get_pipeline_caps (GstVaapiFilter * filter)
311 GST_VAAPI_DISPLAY_LOCK (filter->display);
312 vpp_get_pipeline_caps_unlocked (filter);
313 GST_VAAPI_DISPLAY_UNLOCK (filter->display);
316 /* ------------------------------------------------------------------------- */
317 /* --- VPP Operations --- */
318 /* ------------------------------------------------------------------------- */
320 #define DEFAULT_FORMAT GST_VIDEO_FORMAT_UNKNOWN
322 #define OP_DATA_DEFAULT_VALUE(type, op_data) \
323 g_value_get_##type (g_param_spec_get_default_value (op_data->pspec))
325 #define OP_RET_DEFAULT_VALUE(type, filter, op) \
327 g_return_val_if_fail (filter != NULL, FALSE); \
328 return OP_DATA_DEFAULT_VALUE (type, find_operation (filter, op)); \
340 PROP_FORMAT = GST_VAAPI_FILTER_OP_FORMAT,
341 PROP_CROP = GST_VAAPI_FILTER_OP_CROP,
342 PROP_DENOISE = GST_VAAPI_FILTER_OP_DENOISE,
343 PROP_SHARPEN = GST_VAAPI_FILTER_OP_SHARPEN,
344 PROP_HUE = GST_VAAPI_FILTER_OP_HUE,
345 PROP_SATURATION = GST_VAAPI_FILTER_OP_SATURATION,
346 PROP_BRIGHTNESS = GST_VAAPI_FILTER_OP_BRIGHTNESS,
347 PROP_CONTRAST = GST_VAAPI_FILTER_OP_CONTRAST,
348 PROP_DEINTERLACING = GST_VAAPI_FILTER_OP_DEINTERLACING,
349 PROP_SCALING = GST_VAAPI_FILTER_OP_SCALING,
350 PROP_VIDEO_DIRECTION = GST_VAAPI_FILTER_OP_VIDEO_DIRECTION,
351 PROP_HDR_TONE_MAP = GST_VAAPI_FILTER_OP_HDR_TONE_MAP,
352 #ifndef GST_REMOVE_DEPRECATED
353 PROP_SKINTONE = GST_VAAPI_FILTER_OP_SKINTONE,
355 PROP_SKINTONE_LEVEL = GST_VAAPI_FILTER_OP_SKINTONE_LEVEL,
360 static GParamSpec *g_properties[N_PROPERTIES] = { NULL, };
362 static gsize g_properties_initialized = FALSE;
365 init_properties (void)
368 * GstVaapiFilter:format:
370 * The forced output pixel format, expressed as a #GstVideoFormat.
372 g_properties[PROP_FORMAT] = g_param_spec_enum ("format",
374 "The forced output pixel format",
375 GST_TYPE_VIDEO_FORMAT,
376 DEFAULT_FORMAT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
379 * GstVaapiFilter:crop-rect:
381 * The cropping rectangle, expressed as a #GstVaapiRectangle.
383 g_properties[PROP_CROP] = g_param_spec_boxed ("crop-rect",
384 "Cropping Rectangle",
385 "The cropping rectangle",
386 GST_VAAPI_TYPE_RECTANGLE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
389 * GstVaapiFilter:denoise:
391 * The level of noise reduction to apply.
393 g_properties[PROP_DENOISE] = g_param_spec_float ("denoise",
395 "The level of denoising to apply",
396 0.0, 1.0, 0.0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
399 * GstVaapiFilter:sharpen:
401 * The level of sharpening to apply for positive values, or the
402 * level of blurring for negative values.
404 g_properties[PROP_SHARPEN] = g_param_spec_float ("sharpen",
406 "The level of sharpening/blurring to apply",
407 -1.0, 1.0, 0.0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
410 * GstVaapiFilter:hue:
412 * The color hue, expressed as a float value. Range is -180.0 to
413 * 180.0. Default value is 0.0 and represents no modification.
415 g_properties[PROP_HUE] = g_param_spec_float ("hue",
417 "The color hue value",
418 -180.0, 180.0, 0.0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
421 * GstVaapiFilter:saturation:
423 * The color saturation, expressed as a float value. Range is 0.0 to
424 * 2.0. Default value is 1.0 and represents no modification.
426 g_properties[PROP_SATURATION] = g_param_spec_float ("saturation",
428 "The color saturation value",
429 0.0, 2.0, 1.0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
432 * GstVaapiFilter:brightness:
434 * The color brightness, expressed as a float value. Range is -1.0
435 * to 1.0. Default value is 0.0 and represents no modification.
437 g_properties[PROP_BRIGHTNESS] = g_param_spec_float ("brightness",
439 "The color brightness value",
440 -1.0, 1.0, 0.0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
443 * GstVaapiFilter:contrast:
445 * The color contrast, expressed as a float value. Range is 0.0 to
446 * 2.0. Default value is 1.0 and represents no modification.
448 g_properties[PROP_CONTRAST] = g_param_spec_float ("contrast",
450 "The color contrast value",
451 0.0, 2.0, 1.0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
454 * GstVaapiFilter:deinterlace-method:
456 * The deinterlacing algorithm to apply, expressed a an enum
457 * value. See #GstVaapiDeinterlaceMethod.
459 g_properties[PROP_DEINTERLACING] = g_param_spec_enum ("deinterlace",
460 "Deinterlacing Method",
461 "Deinterlacing method to apply",
462 GST_VAAPI_TYPE_DEINTERLACE_METHOD,
463 GST_VAAPI_DEINTERLACE_METHOD_NONE,
464 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
467 * GstVaapiFilter:scale-method:
469 * The scaling method to use, expressed as an enum value. See
470 * #GstVaapiScaleMethod.
472 g_properties[PROP_SCALING] = g_param_spec_enum ("scale-method",
474 "Scaling method to use",
475 GST_VAAPI_TYPE_SCALE_METHOD,
476 GST_VAAPI_SCALE_METHOD_DEFAULT,
477 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
480 * GstVaapiFilter:video-direction:
482 * The video-direction to use, expressed as an enum value. See
483 * #GstVideoOrientationMethod.
485 g_properties[PROP_VIDEO_DIRECTION] = g_param_spec_enum ("video-direction",
487 "Video direction: rotation and flipping",
488 GST_TYPE_VIDEO_ORIENTATION_METHOD,
489 GST_VIDEO_ORIENTATION_IDENTITY,
490 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
493 * GstVaapiFilter:tone-map:
495 * Apply HDR tone mapping
497 g_properties[PROP_HDR_TONE_MAP] = g_param_spec_boolean ("hdr-tone-map",
499 "Apply HDR tone mapping",
500 FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
502 #ifndef GST_REMOVE_DEPRECATED
504 * GstVaapiFilter:skin-tone-enhancement:
506 * Apply the skin tone enhancement algorithm.
508 g_properties[PROP_SKINTONE] = g_param_spec_boolean ("skin-tone-enhancement",
509 "Skin tone enhancement",
510 "Apply the skin tone enhancement algorithm",
511 FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
515 * GstVaapiFilter:skin-tone-enhancement-level:
517 * Apply the skin tone enhancement algorithm with specified value.
519 g_properties[PROP_SKINTONE_LEVEL] =
520 g_param_spec_uint ("skin-tone-enhancement-level",
521 "Skin tone enhancement level",
522 "Apply the skin tone enhancement algorithm with specified level", 0, 9, 3,
523 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
527 ensure_properties (void)
529 if (g_once_init_enter (&g_properties_initialized)) {
531 g_once_init_leave (&g_properties_initialized, TRUE);
536 op_data_free (GstVaapiFilterOpData * op_data)
538 g_free (op_data->va_caps);
539 g_slice_free (GstVaapiFilterOpData, op_data);
542 static inline gpointer
543 op_data_new (GstVaapiFilterOp op, GParamSpec * pspec)
545 GstVaapiFilterOpData *op_data;
547 op_data = g_slice_new0 (GstVaapiFilterOpData);
552 op_data->pspec = pspec;
553 g_atomic_int_set (&op_data->ref_count, 1);
554 op_data->va_buffer = VA_INVALID_ID;
557 case GST_VAAPI_FILTER_OP_HDR_TONE_MAP:
558 #if VA_CHECK_VERSION(1,4,0)
559 /* Only HDR10 tone mapping is supported */
560 op_data->va_type = VAProcFilterHighDynamicRangeToneMapping;
561 op_data->va_subtype = VAProcHighDynamicRangeMetadataHDR10;
562 op_data->va_cap_size = sizeof (VAProcFilterCapHighDynamicRange);
563 op_data->va_buffer_size =
564 sizeof (VAProcFilterParameterBufferHDRToneMapping);
569 case GST_VAAPI_FILTER_OP_FORMAT:
570 case GST_VAAPI_FILTER_OP_CROP:
571 case GST_VAAPI_FILTER_OP_SCALING:
572 case GST_VAAPI_FILTER_OP_VIDEO_DIRECTION:
573 op_data->va_type = VAProcFilterNone;
575 case GST_VAAPI_FILTER_OP_DENOISE:
576 op_data->va_type = VAProcFilterNoiseReduction;
577 op_data->va_cap_size = sizeof (VAProcFilterCap);
578 op_data->va_buffer_size = sizeof (VAProcFilterParameterBuffer);
580 case GST_VAAPI_FILTER_OP_SHARPEN:
581 op_data->va_type = VAProcFilterSharpening;
582 op_data->va_cap_size = sizeof (VAProcFilterCap);
583 op_data->va_buffer_size = sizeof (VAProcFilterParameterBuffer);
585 #ifndef GST_REMOVE_DEPRECATED
586 case GST_VAAPI_FILTER_OP_SKINTONE:
588 case GST_VAAPI_FILTER_OP_SKINTONE_LEVEL:
589 op_data->va_type = VAProcFilterSkinToneEnhancement;
590 op_data->va_buffer_size = sizeof (VAProcFilterParameterBuffer);
592 case GST_VAAPI_FILTER_OP_HUE:
593 op_data->va_subtype = VAProcColorBalanceHue;
594 goto op_colorbalance;
595 case GST_VAAPI_FILTER_OP_SATURATION:
596 op_data->va_subtype = VAProcColorBalanceSaturation;
597 goto op_colorbalance;
598 case GST_VAAPI_FILTER_OP_BRIGHTNESS:
599 op_data->va_subtype = VAProcColorBalanceBrightness;
600 goto op_colorbalance;
601 case GST_VAAPI_FILTER_OP_CONTRAST:
602 op_data->va_subtype = VAProcColorBalanceContrast;
604 op_data->va_type = VAProcFilterColorBalance;
605 op_data->va_cap_size = sizeof (VAProcFilterCapColorBalance);
606 op_data->va_buffer_size =
607 sizeof (VAProcFilterParameterBufferColorBalance);
609 case GST_VAAPI_FILTER_OP_DEINTERLACING:
610 op_data->va_type = VAProcFilterDeinterlacing;
611 op_data->va_cap_size = sizeof (VAProcFilterCapDeinterlacing);
612 op_data->va_buffer_size =
613 sizeof (VAProcFilterParameterBufferDeinterlacing);
616 g_assert (0 && "unsupported operation");
624 op_data_free (op_data);
629 static inline gpointer
630 op_data_ref (gpointer data)
632 GstVaapiFilterOpData *const op_data = data;
634 g_return_val_if_fail (op_data != NULL, NULL);
636 g_atomic_int_inc (&op_data->ref_count);
641 op_data_unref (gpointer data)
643 GstVaapiFilterOpData *const op_data = data;
645 g_return_if_fail (op_data != NULL);
646 g_return_if_fail (op_data->ref_count > 0);
648 if (g_atomic_int_dec_and_test (&op_data->ref_count))
649 op_data_free (op_data);
652 /* Ensure capability info is set up for the VA filter we are interested in */
654 op_data_ensure_caps (GstVaapiFilterOpData * op_data, gpointer filter_caps,
655 guint num_filter_caps)
657 guchar *filter_cap = filter_caps;
658 guint i, va_num_caps = num_filter_caps;
660 // Find the VA filter cap matching the op info sub-type
661 if (op_data->va_subtype) {
662 for (i = 0; i < num_filter_caps; i++) {
663 /* XXX: sub-type shall always be the first field */
664 if (op_data->va_subtype == *(guint *) filter_cap) {
668 filter_cap += op_data->va_cap_size;
670 if (i == num_filter_caps)
674 op_data->va_caps = g_memdup2 (filter_cap, op_data->va_cap_size * va_num_caps);
675 if (!op_data->va_caps)
678 op_data->va_num_caps = va_num_caps;
682 /* Scale the filter value wrt. library spec and VA driver spec */
684 op_data_get_value_float (GstVaapiFilterOpData * op_data,
685 const VAProcFilterValueRange * range, gfloat value, gfloat * out_value_ptr)
687 GParamSpecFloat *const pspec = G_PARAM_SPEC_FLOAT (op_data->pspec);
690 g_return_val_if_fail (range != NULL, FALSE);
691 g_return_val_if_fail (out_value_ptr != NULL, FALSE);
693 if (value < pspec->minimum || value > pspec->maximum)
696 // Scale wrt. the medium ("default") value
697 out_value = range->default_value;
698 if (value > pspec->default_value)
699 out_value += ((value - pspec->default_value) /
700 (pspec->maximum - pspec->default_value) *
701 (range->max_value - range->default_value));
702 else if (value < pspec->default_value)
703 out_value -= ((pspec->default_value - value) /
704 (pspec->default_value - pspec->minimum) *
705 (range->default_value - range->min_value));
707 *out_value_ptr = out_value;
711 /* Get default list of operations supported by the library */
713 get_operations_default (void)
718 ops = g_ptr_array_new_full (N_PROPERTIES, op_data_unref);
722 ensure_properties ();
724 for (i = 0; i < N_PROPERTIES; i++) {
725 GstVaapiFilterOpData *op_data;
726 GParamSpec *const pspec = g_properties[i];
730 op_data = op_data_new (i, pspec);
733 g_ptr_array_add (ops, op_data);
740 g_ptr_array_unref (ops);
745 /* Get the ordered list of operations, based on VA/VPP queries */
747 get_operations_ordered (GstVaapiFilter * filter, GPtrArray * default_ops)
750 VAProcFilterType *filters;
751 gpointer filter_caps = NULL;
752 guint i, j, num_filters, num_filter_caps = 0;
754 ops = g_ptr_array_new_full (default_ops->len, op_data_unref);
758 filters = vpp_get_filters (filter, &num_filters);
762 // Append virtual ops first, i.e. those without an associated VA filter
763 for (i = 0; i < default_ops->len; i++) {
764 GstVaapiFilterOpData *const op_data = g_ptr_array_index (default_ops, i);
765 if (op_data->va_type == VAProcFilterNone)
766 g_ptr_array_add (ops, op_data_ref (op_data));
769 // Append ops, while preserving the VA filters ordering
770 for (i = 0; i < num_filters; i++) {
771 const VAProcFilterType va_type = filters[i];
772 if (va_type == VAProcFilterNone)
775 for (j = 0; j < default_ops->len; j++) {
776 GstVaapiFilterOpData *const op_data = g_ptr_array_index (default_ops, j);
777 if (op_data->va_type != va_type)
780 if (op_data->va_cap_size == 0) { /* no caps, like skintone */
781 g_ptr_array_add (ops, op_data_ref (op_data));
786 filter_caps = vpp_get_filter_caps (filter, va_type,
787 op_data->va_cap_size, &num_filter_caps);
791 if (!op_data_ensure_caps (op_data, filter_caps, num_filter_caps))
793 g_ptr_array_add (ops, op_data_ref (op_data));
799 vpp_get_pipeline_caps (filter);
801 if (filter->operations)
802 g_ptr_array_unref (filter->operations);
803 filter->operations = g_ptr_array_ref (ops);
806 g_ptr_array_unref (default_ops);
812 g_free (filter_caps);
814 g_ptr_array_unref (ops);
815 g_ptr_array_unref (default_ops);
820 /* Determine the set of supported VPP operations by the specific
821 filter, or known to this library if filter is NULL */
823 get_operations (GstVaapiFilter * filter)
827 if (filter && filter->operations)
828 return g_ptr_array_ref (filter->operations);
830 ops = get_operations_default ();
833 return filter ? get_operations_ordered (filter, ops) : ops;
836 /* Ensure the set of supported VPP operations is cached into the
837 GstVaapiFilter::operations member */
838 static inline gboolean
839 ensure_operations (GstVaapiFilter * filter)
846 if (filter->operations)
849 ops = get_operations (filter);
853 g_ptr_array_unref (ops);
857 /* Find whether the VPP operation is supported or not */
858 static GstVaapiFilterOpData *
859 find_operation (GstVaapiFilter * filter, GstVaapiFilterOp op)
863 if (!ensure_operations (filter))
866 for (i = 0; i < filter->operations->len; i++) {
867 GstVaapiFilterOpData *const op_data =
868 g_ptr_array_index (filter->operations, i);
869 if (op_data->op == op)
875 /* Ensure the operation's VA buffer is allocated */
876 static inline gboolean
877 op_ensure_n_elements_buffer (GstVaapiFilter * filter,
878 GstVaapiFilterOpData * op_data, gint op_num)
880 if (G_LIKELY (op_data->va_buffer != VA_INVALID_ID))
882 return vaapi_create_n_elements_buffer (filter->va_display, filter->va_context,
883 VAProcFilterParameterBufferType, op_data->va_buffer_size, NULL,
884 &op_data->va_buffer, NULL, op_num);
887 static inline gboolean
888 op_ensure_buffer (GstVaapiFilter * filter, GstVaapiFilterOpData * op_data)
890 return op_ensure_n_elements_buffer (filter, op_data, 1);
893 /* Update a generic filter (float value) */
895 op_set_generic_unlocked (GstVaapiFilter * filter,
896 GstVaapiFilterOpData * op_data, gfloat value)
898 VAProcFilterParameterBuffer *buf;
899 VAProcFilterCap *filter_cap;
902 if (!op_data || !op_ensure_buffer (filter, op_data))
905 op_data->is_enabled = (value != OP_DATA_DEFAULT_VALUE (float, op_data));
906 if (!op_data->is_enabled)
909 filter_cap = op_data->va_caps;
910 if (!op_data_get_value_float (op_data, &filter_cap->range, value, &va_value))
913 buf = vaapi_map_buffer (filter->va_display, op_data->va_buffer);
917 buf->type = op_data->va_type;
918 buf->value = va_value;
919 vaapi_unmap_buffer (filter->va_display, op_data->va_buffer, NULL);
923 static inline gboolean
924 op_set_generic (GstVaapiFilter * filter, GstVaapiFilterOpData * op_data,
927 gboolean success = FALSE;
929 GST_VAAPI_DISPLAY_LOCK (filter->display);
930 success = op_set_generic_unlocked (filter, op_data, value);
931 GST_VAAPI_DISPLAY_UNLOCK (filter->display);
935 /* Update the color balance filter */
936 #define COLOR_BALANCE_NUM \
937 GST_VAAPI_FILTER_OP_CONTRAST - GST_VAAPI_FILTER_OP_HUE + 1
940 op_set_color_balance_unlocked (GstVaapiFilter * filter,
941 GstVaapiFilterOpData * op_data, gfloat value)
943 VAProcFilterParameterBufferColorBalance *buf;
944 VAProcFilterCapColorBalance *filter_cap;
947 GstVaapiFilterOpData *color_data[COLOR_BALANCE_NUM];
948 GstVaapiFilterOpData *enabled_data = NULL;
954 /* collect all the Color Balance operators and find the first
956 for (i = 0; i < COLOR_BALANCE_NUM; i++) {
957 color_data[i] = find_operation (filter, GST_VAAPI_FILTER_OP_HUE + i);
961 if (!enabled_data && color_data[i]->is_enabled)
962 enabled_data = color_data[i];
965 /* If there's no enabled operators let's enable this one.
967 * HACK: This operator will be the only one with an allocated buffer
968 * which will store all the color balance operators.
972 if (value == OP_DATA_DEFAULT_VALUE (float, op_data))
976 if (!op_ensure_n_elements_buffer (filter, op_data, COLOR_BALANCE_NUM))
979 enabled_data = op_data;
981 buf = vaapi_map_buffer (filter->va_display, enabled_data->va_buffer);
985 /* Write all the color balance operator values in the buffer. --
986 * Use the default value for all the operators except the set
988 for (i = 0; i < COLOR_BALANCE_NUM; i++) {
989 buf[i].type = color_data[i]->va_type;
990 buf[i].attrib = color_data[i]->va_subtype;
992 va_value = OP_DATA_DEFAULT_VALUE (float, color_data[i]);
993 if (color_data[i]->op == op_data->op) {
994 filter_cap = color_data[i]->va_caps;
995 /* fail but ignore current value and set default one */
996 if (!op_data_get_value_float (color_data[i], &filter_cap->range, value,
1001 buf[i].value = va_value;
1004 enabled_data->is_enabled = 1;
1006 /* There's already one operator enabled, *in theory* with a
1007 * buffer associated. */
1008 if (G_UNLIKELY (enabled_data->va_buffer == VA_INVALID_ID))
1011 filter_cap = op_data->va_caps;
1012 if (!op_data_get_value_float (op_data, &filter_cap->range, value,
1016 buf = vaapi_map_buffer (filter->va_display, enabled_data->va_buffer);
1020 buf[op_data->op - GST_VAAPI_FILTER_OP_HUE].value = va_value;
1023 vaapi_unmap_buffer (filter->va_display, enabled_data->va_buffer, NULL);
1028 static inline gboolean
1029 op_set_color_balance (GstVaapiFilter * filter, GstVaapiFilterOpData * op_data,
1032 gboolean success = FALSE;
1034 GST_VAAPI_DISPLAY_LOCK (filter->display);
1035 success = op_set_color_balance_unlocked (filter, op_data, value);
1036 GST_VAAPI_DISPLAY_UNLOCK (filter->display);
1040 /* Update deinterlace filter */
1042 op_set_deinterlace_unlocked (GstVaapiFilter * filter,
1043 GstVaapiFilterOpData * op_data, GstVaapiDeinterlaceMethod method,
1046 VAProcFilterParameterBufferDeinterlacing *buf;
1047 const VAProcFilterCapDeinterlacing *filter_caps;
1048 VAProcDeinterlacingType algorithm;
1051 if (!op_data || !op_ensure_buffer (filter, op_data))
1054 op_data->is_enabled = (method != GST_VAAPI_DEINTERLACE_METHOD_NONE);
1055 if (!op_data->is_enabled)
1058 algorithm = from_GstVaapiDeinterlaceMethod (method);
1059 for (i = 0, filter_caps = op_data->va_caps; i < op_data->va_num_caps; i++) {
1060 if (filter_caps[i].type == algorithm)
1063 if (i == op_data->va_num_caps)
1066 buf = vaapi_map_buffer (filter->va_display, op_data->va_buffer);
1070 buf->type = op_data->va_type;
1071 buf->algorithm = algorithm;
1072 buf->flags = from_GstVaapiDeinterlaceFlags (flags);
1073 vaapi_unmap_buffer (filter->va_display, op_data->va_buffer, NULL);
1077 static inline gboolean
1078 op_set_deinterlace (GstVaapiFilter * filter, GstVaapiFilterOpData * op_data,
1079 GstVaapiDeinterlaceMethod method, guint flags)
1081 gboolean success = FALSE;
1083 GST_VAAPI_DISPLAY_LOCK (filter->display);
1084 success = op_set_deinterlace_unlocked (filter, op_data, method, flags);
1085 GST_VAAPI_DISPLAY_UNLOCK (filter->display);
1089 /* Update skin tone enhancement level */
1091 op_set_skintone_level_unlocked (GstVaapiFilter * filter,
1092 GstVaapiFilterOpData * op_data, guint value)
1094 VAProcFilterParameterBuffer *buf;
1096 if (!op_data || !op_ensure_buffer (filter, op_data))
1099 op_data->is_enabled = 1;
1101 buf = vaapi_map_buffer (filter->va_display, op_data->va_buffer);
1104 buf->type = op_data->va_type;
1106 vaapi_unmap_buffer (filter->va_display, op_data->va_buffer, NULL);
1110 static inline gboolean
1111 op_set_skintone_level (GstVaapiFilter * filter,
1112 GstVaapiFilterOpData * op_data, guint value)
1114 gboolean success = FALSE;
1116 GST_VAAPI_DISPLAY_LOCK (filter->display);
1117 success = op_set_skintone_level_unlocked (filter, op_data, value);
1118 GST_VAAPI_DISPLAY_UNLOCK (filter->display);
1122 #ifndef GST_REMOVE_DEPRECATED
1123 /* Update skin tone enhancement */
1125 op_set_skintone_unlocked (GstVaapiFilter * filter,
1126 GstVaapiFilterOpData * op_data, gboolean value)
1132 op_data->is_enabled = 0;
1136 return op_set_skintone_level_unlocked (filter, op_data, 3);
1139 static inline gboolean
1140 op_set_skintone (GstVaapiFilter * filter, GstVaapiFilterOpData * op_data,
1143 gboolean success = FALSE;
1145 GST_VAAPI_DISPLAY_LOCK (filter->display);
1146 success = op_set_skintone_unlocked (filter, op_data, enhance);
1147 GST_VAAPI_DISPLAY_UNLOCK (filter->display);
1153 op_set_hdr_tone_map_unlocked (GstVaapiFilter * filter,
1154 GstVaapiFilterOpData * op_data, gboolean value)
1156 #if VA_CHECK_VERSION(1,4,0)
1157 const VAProcFilterCapHighDynamicRange *filter_caps;
1164 op_data->is_enabled = 0;
1168 if (!op_ensure_buffer (filter, op_data))
1171 for (i = 0, filter_caps = op_data->va_caps; i < op_data->va_num_caps; i++) {
1172 if (filter_caps[i].metadata_type == op_data->va_subtype &&
1173 (filter_caps[i].caps_flag & VA_TONE_MAPPING_HDR_TO_SDR))
1176 if (i == op_data->va_num_caps)
1179 op_data->is_enabled = 1;
1187 static inline gboolean
1188 op_set_hdr_tone_map (GstVaapiFilter * filter, GstVaapiFilterOpData * op_data,
1191 gboolean success = FALSE;
1192 GST_VAAPI_DISPLAY_LOCK (filter->display);
1193 success = op_set_hdr_tone_map_unlocked (filter, op_data, value);
1194 GST_VAAPI_DISPLAY_UNLOCK (filter->display);
1200 deint_refs_set (GArray * refs, GstVaapiSurface ** surfaces, guint num_surfaces)
1204 if (num_surfaces > 0 && !surfaces)
1207 for (i = 0; i < num_surfaces; i++)
1208 g_array_append_val (refs, GST_VAAPI_SURFACE_ID (surfaces[i]));
1213 deint_refs_clear (GArray * refs)
1216 g_array_remove_range (refs, 0, refs->len);
1220 deint_refs_clear_all (GstVaapiFilter * filter)
1222 deint_refs_clear (filter->forward_references);
1223 deint_refs_clear (filter->backward_references);
1226 /* ------------------------------------------------------------------------- */
1227 /* --- Surface Attribs --- */
1228 /* ------------------------------------------------------------------------- */
1231 ensure_attributes (GstVaapiFilter * filter)
1233 if (G_LIKELY (filter->attribs))
1236 filter->attribs = gst_vaapi_config_surface_attributes_get (filter->display,
1238 return (filter->attribs != NULL);
1241 static inline gboolean
1242 is_special_format (GstVideoFormat format)
1244 return format == GST_VIDEO_FORMAT_UNKNOWN ||
1245 format == GST_VIDEO_FORMAT_ENCODED;
1249 find_format (GstVaapiFilter * filter, GstVideoFormat format)
1254 formats = filter->attribs->formats;
1255 if (is_special_format (format) || !formats)
1258 for (i = 0; i < formats->len; i++) {
1259 if (g_array_index (formats, GstVideoFormat, i) == format)
1265 /* ------------------------------------------------------------------------- */
1266 /* --- Interface --- */
1267 /* ------------------------------------------------------------------------- */
1270 gst_vaapi_filter_init (GstVaapiFilter * filter)
1272 filter->va_config = VA_INVALID_ID;
1273 filter->va_context = VA_INVALID_ID;
1274 filter->format = DEFAULT_FORMAT;
1276 filter->forward_references =
1277 g_array_sized_new (FALSE, FALSE, sizeof (VASurfaceID), 4);
1279 filter->backward_references =
1280 g_array_sized_new (FALSE, FALSE, sizeof (VASurfaceID), 4);
1284 gst_vaapi_filter_initialize (GstVaapiFilter * filter)
1288 if (!filter->display)
1291 va_status = vaCreateConfig (filter->va_display, VAProfileNone,
1292 VAEntrypointVideoProc, NULL, 0, &filter->va_config);
1293 if (!vaapi_check_status (va_status, "vaCreateConfig() [VPP]"))
1296 va_status = vaCreateContext (filter->va_display, filter->va_config, 0, 0, 0,
1297 NULL, 0, &filter->va_context);
1298 if (!vaapi_check_status (va_status, "vaCreateContext() [VPP]"))
1301 gst_video_colorimetry_from_string (&filter->input_colorimetry, NULL);
1302 gst_video_colorimetry_from_string (&filter->output_colorimetry, NULL);
1308 gst_vaapi_filter_finalize (GObject * object)
1310 GstVaapiFilter *const filter = GST_VAAPI_FILTER (object);
1313 if (!filter->display)
1316 GST_VAAPI_DISPLAY_LOCK (filter->display);
1317 if (filter->operations) {
1318 for (i = 0; i < filter->operations->len; i++) {
1319 GstVaapiFilterOpData *const op_data =
1320 g_ptr_array_index (filter->operations, i);
1321 vaapi_destroy_buffer (filter->va_display, &op_data->va_buffer);
1323 g_ptr_array_unref (filter->operations);
1324 filter->operations = NULL;
1327 if (filter->va_context != VA_INVALID_ID) {
1328 vaDestroyContext (filter->va_display, filter->va_context);
1329 filter->va_context = VA_INVALID_ID;
1332 if (filter->va_config != VA_INVALID_ID) {
1333 vaDestroyConfig (filter->va_display, filter->va_config);
1334 filter->va_config = VA_INVALID_ID;
1336 GST_VAAPI_DISPLAY_UNLOCK (filter->display);
1337 gst_vaapi_display_replace (&filter->display, NULL);
1340 if (filter->forward_references) {
1341 g_array_unref (filter->forward_references);
1342 filter->forward_references = NULL;
1345 if (filter->backward_references) {
1346 g_array_unref (filter->backward_references);
1347 filter->backward_references = NULL;
1350 if (filter->attribs) {
1351 gst_vaapi_config_surface_attributes_free (filter->attribs);
1352 filter->attribs = NULL;
1355 G_OBJECT_CLASS (gst_vaapi_filter_parent_class)->finalize (object);
1359 gst_vaapi_filter_set_property (GObject * object, guint property_id,
1360 const GValue * value, GParamSpec * pspec)
1362 GstVaapiFilter *const filter = GST_VAAPI_FILTER (object);
1364 switch (property_id) {
1366 GstVaapiDisplay *display = g_value_get_object (value);;
1369 if (GST_VAAPI_DISPLAY_HAS_VPP (display)) {
1370 filter->display = gst_object_ref (display);
1371 filter->va_display = GST_VAAPI_DISPLAY_VADISPLAY (filter->display);
1373 GST_WARNING_OBJECT (filter, "VA display doesn't support VPP");
1379 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
1384 gst_vaapi_filter_get_property (GObject * object, guint property_id,
1385 GValue * value, GParamSpec * pspec)
1387 GstVaapiFilter *const filter = GST_VAAPI_FILTER (object);
1389 switch (property_id) {
1391 g_value_set_object (value, filter->display);
1394 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
1399 gst_vaapi_filter_class_init (GstVaapiFilterClass * klass)
1401 GObjectClass *const object_class = G_OBJECT_CLASS (klass);
1403 object_class->set_property = gst_vaapi_filter_set_property;
1404 object_class->get_property = gst_vaapi_filter_get_property;
1405 object_class->finalize = gst_vaapi_filter_finalize;
1408 * GstVaapiFilter:display:
1410 * #GstVaapiDisplay to be used.
1412 g_object_class_install_property (object_class, PROP_DISPLAY,
1413 g_param_spec_object ("display", "Gst VA-API Display",
1414 "The VA-API display object to use", GST_TYPE_VAAPI_DISPLAY,
1415 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_NAME));
1419 * gst_vaapi_filter_new:
1420 * @display: a #GstVaapiDisplay
1422 * Creates a new #GstVaapiFilter set up to operate in "identity"
1423 * mode. This means that no other operation than scaling is performed.
1425 * Return value: the newly created #GstVaapiFilter object
1428 gst_vaapi_filter_new (GstVaapiDisplay * display)
1430 GstVaapiFilter *filter;
1432 filter = g_object_new (GST_TYPE_VAAPI_FILTER, "display", display, NULL);
1433 if (!gst_vaapi_filter_initialize (filter))
1440 gst_object_unref (filter);
1446 * gst_vaapi_filter_replace:
1447 * @old_filter_ptr: a pointer to a #GstVaapiFilter
1448 * @new_filter: a #GstVaapiFilter
1450 * Atomically replaces the filter held in @old_filter_ptr with
1451 * @new_filter. This means that @old_filter_ptr shall reference a
1452 * valid filter. However, @new_filter can be NULL.
1455 gst_vaapi_filter_replace (GstVaapiFilter ** old_filter_ptr,
1456 GstVaapiFilter * new_filter)
1458 g_return_if_fail (old_filter_ptr != NULL);
1460 gst_object_replace ((GstObject **) old_filter_ptr, GST_OBJECT (new_filter));
1464 * gst_vaapi_filter_get_operations:
1465 * @filter: a #GstVaapiFilter, or %NULL
1467 * Determines the set of supported operations for video processing.
1468 * The caller owns an extra reference to the resulting array of
1469 * #GstVaapiFilterOpInfo elements, so it shall be released with
1470 * g_ptr_array_unref() after usage.
1472 * If @filter is %NULL, then this function returns the video
1473 * processing operations supported by this library.
1475 * Return value: the set of supported operations, or %NULL if an error
1479 gst_vaapi_filter_get_operations (GstVaapiFilter * filter)
1481 return get_operations (filter);
1485 * gst_vaapi_filter_has_operation:
1486 * @filter: a #GstVaapiFilter
1487 * @op: a #GstVaapiFilterOp
1489 * Determines whether the underlying VA driver advertises support for
1490 * the supplied operation @op.
1492 * Return value: %TRUE if the specified operation may be supported by
1493 * the underlying hardware, %FALSE otherwise
1496 gst_vaapi_filter_has_operation (GstVaapiFilter * filter, GstVaapiFilterOp op)
1498 g_return_val_if_fail (filter != NULL, FALSE);
1500 return find_operation (filter, op) != NULL;
1504 * gst_vaapi_filter_use_operation:
1505 * @filter: a #GstVaapiFilter
1506 * @op: a #GstVaapiFilterOp
1508 * Determines whether the supplied operation @op was already enabled
1509 * through a prior call to gst_vaapi_filter_set_operation() or any
1510 * other operation-specific function.
1512 * Note: should an operation be set to its default value, this means
1513 * that it is actually not enabled.
1515 * Return value: %TRUE if the specified operation was already enabled,
1519 gst_vaapi_filter_use_operation (GstVaapiFilter * filter, GstVaapiFilterOp op)
1521 GstVaapiFilterOpData *op_data;
1523 g_return_val_if_fail (filter != NULL, FALSE);
1525 op_data = find_operation (filter, op);
1528 return op_data->is_enabled;
1532 * gst_vaapi_filter_set_operation:
1533 * @filter: a #GstVaapiFilter
1534 * @op: a #GstVaapiFilterOp
1535 * @value: the @op settings
1537 * Enable the specified operation @op to be performed during video
1538 * processing, i.e. in gst_vaapi_filter_process(). The @value argument
1539 * specifies the operation settings. e.g. deinterlacing method for
1540 * deinterlacing, denoising level for noise reduction, etc.
1542 * If @value is %NULL, then this function resets the operation
1543 * settings to their default values.
1545 * Return value: %TRUE if the specified operation may be supported,
1549 gst_vaapi_filter_set_operation (GstVaapiFilter * filter, GstVaapiFilterOp op,
1550 const GValue * value)
1552 GstVaapiFilterOpData *op_data;
1554 g_return_val_if_fail (filter != NULL, FALSE);
1556 op_data = find_operation (filter, op);
1560 if (value && !G_VALUE_HOLDS (value, G_PARAM_SPEC_VALUE_TYPE (op_data->pspec)))
1564 case GST_VAAPI_FILTER_OP_FORMAT:
1565 return gst_vaapi_filter_set_format (filter, value ?
1566 g_value_get_enum (value) : DEFAULT_FORMAT);
1567 case GST_VAAPI_FILTER_OP_CROP:
1568 return gst_vaapi_filter_set_cropping_rectangle (filter, value ?
1569 g_value_get_boxed (value) : NULL);
1570 case GST_VAAPI_FILTER_OP_DENOISE:
1571 case GST_VAAPI_FILTER_OP_SHARPEN:
1572 return op_set_generic (filter, op_data,
1573 (value ? g_value_get_float (value) :
1574 OP_DATA_DEFAULT_VALUE (float, op_data)));
1575 case GST_VAAPI_FILTER_OP_HUE:
1576 case GST_VAAPI_FILTER_OP_SATURATION:
1577 case GST_VAAPI_FILTER_OP_BRIGHTNESS:
1578 case GST_VAAPI_FILTER_OP_CONTRAST:
1579 return op_set_color_balance (filter, op_data,
1580 (value ? g_value_get_float (value) :
1581 OP_DATA_DEFAULT_VALUE (float, op_data)));
1582 case GST_VAAPI_FILTER_OP_DEINTERLACING:
1583 return op_set_deinterlace (filter, op_data,
1584 (value ? g_value_get_enum (value) :
1585 OP_DATA_DEFAULT_VALUE (enum, op_data)), 0);
1587 case GST_VAAPI_FILTER_OP_SCALING:
1588 return gst_vaapi_filter_set_scaling (filter,
1589 (value ? g_value_get_enum (value) :
1590 OP_DATA_DEFAULT_VALUE (enum, op_data)));
1591 #ifndef GST_REMOVE_DEPRECATED
1592 case GST_VAAPI_FILTER_OP_SKINTONE:
1593 return op_set_skintone (filter, op_data,
1594 (value ? g_value_get_boolean (value) :
1595 OP_DATA_DEFAULT_VALUE (boolean, op_data)));
1597 case GST_VAAPI_FILTER_OP_SKINTONE_LEVEL:
1598 return op_set_skintone_level (filter, op_data,
1599 (value ? g_value_get_uint (value) :
1600 OP_DATA_DEFAULT_VALUE (uint, op_data)));
1601 case GST_VAAPI_FILTER_OP_VIDEO_DIRECTION:
1602 return gst_vaapi_filter_set_video_direction (filter,
1603 (value ? g_value_get_enum (value) :
1604 OP_DATA_DEFAULT_VALUE (enum, op_data)));
1605 case GST_VAAPI_FILTER_OP_HDR_TONE_MAP:
1606 return op_set_hdr_tone_map (filter, op_data,
1607 (value ? g_value_get_boolean (value) :
1608 OP_DATA_DEFAULT_VALUE (boolean, op_data)));
1615 #if VA_CHECK_VERSION(1,2,0)
1617 fill_color_standard (GstVideoColorimetry * colorimetry,
1618 VAProcColorStandardType * type, VAProcColorProperties * properties)
1620 *type = from_GstVideoColorimetry (colorimetry);
1622 properties->colour_primaries =
1623 gst_video_color_primaries_to_iso (colorimetry->primaries);
1624 properties->transfer_characteristics =
1625 gst_video_transfer_function_to_iso (colorimetry->transfer);
1626 properties->matrix_coefficients =
1627 gst_video_color_matrix_to_iso (colorimetry->matrix);
1629 properties->color_range = from_GstVideoColorRange (colorimetry->range);
1634 gst_vaapi_filter_fill_color_standards (GstVaapiFilter * filter,
1635 VAProcPipelineParameterBuffer * pipeline_param)
1637 #if VA_CHECK_VERSION(1,2,0)
1638 fill_color_standard (&filter->input_colorimetry,
1639 &pipeline_param->surface_color_standard,
1640 &pipeline_param->input_color_properties);
1642 fill_color_standard (&filter->output_colorimetry,
1643 &pipeline_param->output_color_standard,
1644 &pipeline_param->output_color_properties);
1646 pipeline_param->surface_color_standard = VAProcColorStandardNone;
1647 pipeline_param->output_color_standard = VAProcColorStandardNone;
1652 * gst_vaapi_filter_process:
1653 * @filter: a #GstVaapiFilter
1654 * @src_surface: the source @GstVaapiSurface
1655 * @dst_surface: the destination @GstVaapiSurface
1656 * @flags: #GstVaapiSurfaceRenderFlags that apply to @src_surface
1658 * Applies the operations currently defined in the @filter to
1659 * @src_surface and return the output in @dst_surface. The order of
1660 * operations is determined in a way that suits best the underlying
1661 * hardware. i.e. the only guarantee held is the generated outcome,
1662 * not any specific order of operations.
1664 * Return value: a #GstVaapiFilterStatus
1666 static GstVaapiFilterStatus
1667 gst_vaapi_filter_process_unlocked (GstVaapiFilter * filter,
1668 GstVaapiSurface * src_surface, GstVaapiSurface * dst_surface, guint flags)
1670 VAProcPipelineParameterBuffer *pipeline_param = NULL;
1671 VABufferID pipeline_param_buf_id = VA_INVALID_ID;
1672 VABufferID filters[N_PROPERTIES];
1673 VAProcPipelineCaps pipeline_caps;
1674 guint i, num_filters = 0;
1676 VARectangle src_rect, dst_rect;
1677 guint va_mirror = 0, va_rotation = 0;
1679 if (!ensure_operations (filter))
1680 return GST_VAAPI_FILTER_STATUS_ERROR_ALLOCATION_FAILED;
1682 /* Build surface region (source) */
1683 if (filter->use_crop_rect) {
1684 const GstVaapiRectangle *const crop_rect = &filter->crop_rect;
1686 if ((crop_rect->x + crop_rect->width >
1687 GST_VAAPI_SURFACE_WIDTH (src_surface)) ||
1688 (crop_rect->y + crop_rect->height >
1689 GST_VAAPI_SURFACE_HEIGHT (src_surface)))
1692 src_rect.x = crop_rect->x;
1693 src_rect.y = crop_rect->y;
1694 src_rect.width = crop_rect->width;
1695 src_rect.height = crop_rect->height;
1699 src_rect.width = GST_VAAPI_SURFACE_WIDTH (src_surface);
1700 src_rect.height = GST_VAAPI_SURFACE_HEIGHT (src_surface);
1703 /* Build output region (target) */
1704 if (filter->use_target_rect) {
1705 const GstVaapiRectangle *const target_rect = &filter->target_rect;
1707 if ((target_rect->x + target_rect->width >
1708 GST_VAAPI_SURFACE_WIDTH (dst_surface)) ||
1709 (target_rect->y + target_rect->height >
1710 GST_VAAPI_SURFACE_HEIGHT (dst_surface)))
1713 dst_rect.x = target_rect->x;
1714 dst_rect.y = target_rect->y;
1715 dst_rect.width = target_rect->width;
1716 dst_rect.height = target_rect->height;
1720 dst_rect.width = GST_VAAPI_SURFACE_WIDTH (dst_surface);
1721 dst_rect.height = GST_VAAPI_SURFACE_HEIGHT (dst_surface);
1724 for (i = 0, num_filters = 0; i < filter->operations->len; i++) {
1725 GstVaapiFilterOpData *const op_data =
1726 g_ptr_array_index (filter->operations, i);
1727 if (!op_data->is_enabled)
1729 if (op_data->va_buffer == VA_INVALID_ID) {
1730 GST_ERROR ("invalid VA buffer for operation %s",
1731 g_param_spec_get_name (op_data->pspec));
1734 filters[num_filters++] = op_data->va_buffer;
1737 /* Validate pipeline caps */
1738 va_status = vaQueryVideoProcPipelineCaps (filter->va_display,
1739 filter->va_context, filters, num_filters, &pipeline_caps);
1740 if (!vaapi_check_status (va_status, "vaQueryVideoProcPipelineCaps()"))
1743 if (!vaapi_create_buffer (filter->va_display, filter->va_context,
1744 VAProcPipelineParameterBufferType, sizeof (*pipeline_param),
1745 NULL, &pipeline_param_buf_id, (gpointer *) & pipeline_param))
1748 memset (pipeline_param, 0, sizeof (*pipeline_param));
1749 pipeline_param->surface = GST_VAAPI_SURFACE_ID (src_surface);
1750 pipeline_param->surface_region = &src_rect;
1752 gst_vaapi_filter_fill_color_standards (filter, pipeline_param);
1754 pipeline_param->output_region = &dst_rect;
1755 pipeline_param->output_background_color = 0xff000000;
1756 pipeline_param->filter_flags = from_GstVaapiSurfaceRenderFlags (flags) |
1757 from_GstVaapiScaleMethod (filter->scale_method);
1758 pipeline_param->filters = filters;
1759 pipeline_param->num_filters = num_filters;
1761 from_GstVideoOrientationMethod (filter->video_direction, &va_mirror,
1764 #if VA_CHECK_VERSION(1,1,0)
1765 pipeline_param->mirror_state = va_mirror;
1766 pipeline_param->rotation_state = va_rotation;
1769 // Reference frames for advanced deinterlacing
1770 if (filter->forward_references->len > 0) {
1771 pipeline_param->forward_references = (VASurfaceID *)
1772 filter->forward_references->data;
1773 pipeline_param->num_forward_references =
1774 MIN (filter->forward_references->len,
1775 pipeline_caps.num_forward_references);
1777 pipeline_param->forward_references = NULL;
1778 pipeline_param->num_forward_references = 0;
1781 if (filter->backward_references->len > 0) {
1782 pipeline_param->backward_references = (VASurfaceID *)
1783 filter->backward_references->data;
1784 pipeline_param->num_backward_references =
1785 MIN (filter->backward_references->len,
1786 pipeline_caps.num_backward_references);
1788 pipeline_param->backward_references = NULL;
1789 pipeline_param->num_backward_references = 0;
1792 vaapi_unmap_buffer (filter->va_display, pipeline_param_buf_id, NULL);
1794 va_status = vaBeginPicture (filter->va_display, filter->va_context,
1795 GST_VAAPI_SURFACE_ID (dst_surface));
1796 if (!vaapi_check_status (va_status, "vaBeginPicture()"))
1799 va_status = vaRenderPicture (filter->va_display, filter->va_context,
1800 &pipeline_param_buf_id, 1);
1801 if (!vaapi_check_status (va_status, "vaRenderPicture()"))
1804 va_status = vaEndPicture (filter->va_display, filter->va_context);
1805 if (!vaapi_check_status (va_status, "vaEndPicture()"))
1808 deint_refs_clear_all (filter);
1809 vaapi_destroy_buffer (filter->va_display, &pipeline_param_buf_id);
1810 return GST_VAAPI_FILTER_STATUS_SUCCESS;
1815 deint_refs_clear_all (filter);
1816 vaapi_destroy_buffer (filter->va_display, &pipeline_param_buf_id);
1817 return GST_VAAPI_FILTER_STATUS_ERROR_OPERATION_FAILED;
1821 GstVaapiFilterStatus
1822 gst_vaapi_filter_process (GstVaapiFilter * filter,
1823 GstVaapiSurface * src_surface, GstVaapiSurface * dst_surface, guint flags)
1825 GstVaapiFilterStatus status;
1827 g_return_val_if_fail (filter != NULL,
1828 GST_VAAPI_FILTER_STATUS_ERROR_INVALID_PARAMETER);
1829 g_return_val_if_fail (src_surface != NULL,
1830 GST_VAAPI_FILTER_STATUS_ERROR_INVALID_PARAMETER);
1831 g_return_val_if_fail (dst_surface != NULL,
1832 GST_VAAPI_FILTER_STATUS_ERROR_INVALID_PARAMETER);
1834 GST_VAAPI_DISPLAY_LOCK (filter->display);
1835 status = gst_vaapi_filter_process_unlocked (filter,
1836 src_surface, dst_surface, flags);
1837 GST_VAAPI_DISPLAY_UNLOCK (filter->display);
1842 * gst_vaapi_filter_get_formats:
1843 * @filter: a #GstVaapiFilter
1845 * Determines the set of supported source or target formats for video
1846 * processing. The caller owns an extra reference to the resulting
1847 * array of #GstVideoFormat elements, so it shall be released with
1848 * g_array_unref() after usage.
1850 * Return value: the set of supported target formats for video processing.
1853 gst_vaapi_filter_get_formats (GstVaapiFilter * filter)
1855 g_return_val_if_fail (filter != NULL, NULL);
1857 if (!ensure_attributes (filter))
1859 if (filter->attribs->formats)
1860 return g_array_ref (filter->attribs->formats);
1865 * gst_vaapi_filter_set_format:
1866 * @filter: a #GstVaapiFilter
1867 * @format: the target surface format
1869 * Sets the desired pixel format of the resulting video processing
1872 * If @format is #GST_VIDEO_FORMAT_UNKNOWN, the filter will assume iso
1873 * format conversion, i.e. no color conversion at all and the target
1874 * surface format shall match the source surface format.
1876 * If @format is #GST_VIDEO_FORMAT_ENCODED, the filter will use the pixel
1877 * format of the target surface passed to gst_vaapi_filter_process().
1879 * Return value: %TRUE if the color conversion to the specified @format
1880 * may be supported, %FALSE otherwise.
1883 gst_vaapi_filter_set_format (GstVaapiFilter * filter, GstVideoFormat format)
1885 g_return_val_if_fail (filter != NULL, FALSE);
1887 if (!ensure_attributes (filter))
1890 if (!is_special_format (format) && !find_format (filter, format))
1893 filter->format = format;
1898 * gst_vaapi_filter_append_caps:
1899 * @filter: a #GstVaapiFilter
1900 * @structure: a #GstStructure from #GstCaps
1902 * Extracts the config's surface attributes, from @filter's context,
1903 * and transforms it into a caps formats and appended them into
1906 * Returns: %TRUE if the capabilities could be extracted and appended
1907 * into @structure; otherwise %FALSE
1910 gst_vaapi_filter_append_caps (GstVaapiFilter * filter, GstStructure * structure)
1912 GstVaapiConfigSurfaceAttributes *attribs;
1914 g_return_val_if_fail (filter != NULL, FALSE);
1915 g_return_val_if_fail (structure != NULL, FALSE);
1917 if (!ensure_attributes (filter))
1920 attribs = filter->attribs;
1922 if (attribs->min_width >= attribs->max_width ||
1923 attribs->min_height >= attribs->max_height)
1926 gst_structure_set (structure, "width", GST_TYPE_INT_RANGE, attribs->min_width,
1927 attribs->max_width, "height", GST_TYPE_INT_RANGE, attribs->min_height,
1928 attribs->max_height, NULL);
1935 * gst_vaapi_filter_get_memory_types:
1936 * @filter: a #GstVaapiFilter
1938 * Gets the surface's memory types available in @filter's context.
1940 * Returns: surface's memory types available in @filter context.
1943 gst_vaapi_filter_get_memory_types (GstVaapiFilter * filter)
1945 g_return_val_if_fail (filter != NULL, FALSE);
1947 if (!ensure_attributes (filter))
1949 return filter->attribs->mem_types;
1953 * gst_vaapi_filter_set_cropping_rectangle:
1954 * @filter: a #GstVaapiFilter
1955 * @rect: the cropping region
1957 * Sets the source surface cropping rectangle to use during the video
1958 * processing. If @rect is %NULL, the whole source surface will be used.
1960 * Return value: %TRUE if the operation is supported, %FALSE otherwise.
1963 gst_vaapi_filter_set_cropping_rectangle (GstVaapiFilter * filter,
1964 const GstVaapiRectangle * rect)
1966 g_return_val_if_fail (filter != NULL, FALSE);
1968 filter->use_crop_rect = rect != NULL;
1969 if (filter->use_crop_rect)
1970 filter->crop_rect = *rect;
1975 * gst_vaapi_filter_set_target_rectangle:
1976 * @filter: a #GstVaapiFilter
1977 * @rect: the target render region
1979 * Sets the region within the target surface where the source surface
1980 * would be rendered. i.e. where the hardware accelerator would emit
1981 * the outcome of video processing. If @rect is %NULL, the whole
1982 * source surface will be used.
1984 * Return value: %TRUE if the operation is supported, %FALSE otherwise.
1987 gst_vaapi_filter_set_target_rectangle (GstVaapiFilter * filter,
1988 const GstVaapiRectangle * rect)
1990 g_return_val_if_fail (filter != NULL, FALSE);
1992 filter->use_target_rect = rect != NULL;
1993 if (filter->use_target_rect)
1994 filter->target_rect = *rect;
1999 * gst_vaapi_filter_set_denoising_level:
2000 * @filter: a #GstVaapiFilter
2001 * @level: the level of noise reduction to apply
2003 * Sets the noise reduction level to apply. If @level is 0.0f, this
2004 * corresponds to disabling the noise reduction algorithm.
2006 * Return value: %TRUE if the operation is supported, %FALSE otherwise.
2009 gst_vaapi_filter_set_denoising_level (GstVaapiFilter * filter, gfloat level)
2011 g_return_val_if_fail (filter != NULL, FALSE);
2013 return op_set_generic (filter,
2014 find_operation (filter, GST_VAAPI_FILTER_OP_DENOISE), level);
2018 * gst_vaapi_filter_set_sharpening_level:
2019 * @filter: a #GstVaapiFilter
2020 * @level: the sharpening factor
2022 * Enables noise reduction with the specified factor.
2024 * Return value: %TRUE if the operation is supported, %FALSE otherwise.
2027 gst_vaapi_filter_set_sharpening_level (GstVaapiFilter * filter, gfloat level)
2029 g_return_val_if_fail (filter != NULL, FALSE);
2031 return op_set_generic (filter,
2032 find_operation (filter, GST_VAAPI_FILTER_OP_SHARPEN), level);
2036 * gst_vaapi_filter_set_hue:
2037 * @filter: a #GstVaapiFilter
2038 * @value: the color hue value
2040 * Enables color hue adjustment to the specified value.
2042 * Return value: %TRUE if the operation is supported, %FALSE otherwise.
2045 gst_vaapi_filter_set_hue (GstVaapiFilter * filter, gfloat value)
2047 g_return_val_if_fail (filter != NULL, FALSE);
2049 return op_set_color_balance (filter,
2050 find_operation (filter, GST_VAAPI_FILTER_OP_HUE), value);
2054 * gst_vaapi_filter_set_saturation:
2055 * @filter: a #GstVaapiFilter
2056 * @value: the color saturation value
2058 * Enables color saturation adjustment to the specified value.
2060 * Return value: %TRUE if the operation is supported, %FALSE otherwise.
2063 gst_vaapi_filter_set_saturation (GstVaapiFilter * filter, gfloat value)
2065 g_return_val_if_fail (filter != NULL, FALSE);
2067 return op_set_color_balance (filter,
2068 find_operation (filter, GST_VAAPI_FILTER_OP_SATURATION), value);
2072 * gst_vaapi_filter_set_brightness:
2073 * @filter: a #GstVaapiFilter
2074 * @value: the color brightness value
2076 * Enables color brightness adjustment to the specified value.
2078 * Return value: %TRUE if the operation is supported, %FALSE otherwise.
2081 gst_vaapi_filter_set_brightness (GstVaapiFilter * filter, gfloat value)
2083 g_return_val_if_fail (filter != NULL, FALSE);
2085 return op_set_color_balance (filter,
2086 find_operation (filter, GST_VAAPI_FILTER_OP_BRIGHTNESS), value);
2090 * gst_vaapi_filter_set_contrast:
2091 * @filter: a #GstVaapiFilter
2092 * @value: the color contrast value
2094 * Enables color contrast adjustment to the specified value.
2096 * Return value: %TRUE if the operation is supported, %FALSE otherwise.
2099 gst_vaapi_filter_set_contrast (GstVaapiFilter * filter, gfloat value)
2101 g_return_val_if_fail (filter != NULL, FALSE);
2103 return op_set_color_balance (filter,
2104 find_operation (filter, GST_VAAPI_FILTER_OP_CONTRAST), value);
2108 * gst_vaapi_filter_set_deinterlacing:
2109 * @filter: a #GstVaapiFilter
2110 * @method: the deinterlacing algorithm (see #GstVaapiDeinterlaceMethod)
2111 * @flags: the additional flags
2113 * Applies deinterlacing to the video processing pipeline. If @method
2114 * is not @GST_VAAPI_DEINTERLACE_METHOD_NONE, then @flags could
2115 * represent the initial picture structure of the source frame.
2117 * Return value: %TRUE if the operation is supported, %FALSE otherwise.
2120 gst_vaapi_filter_set_deinterlacing (GstVaapiFilter * filter,
2121 GstVaapiDeinterlaceMethod method, guint flags)
2123 g_return_val_if_fail (filter != NULL, FALSE);
2125 return op_set_deinterlace (filter,
2126 find_operation (filter, GST_VAAPI_FILTER_OP_DEINTERLACING), method,
2131 * gst_vaapi_filter_set_deinterlacing_references:
2132 * @filter: a #GstVaapiFilter
2133 * @forward_references: the set of #GstVaapiSurface objects used as
2134 * forward references
2135 * @num_forward_references: the number of elements in the
2136 * @forward_references array
2137 * @backward_references: the set of #GstVaapiSurface objects used as
2138 * backward references
2139 * @num_backward_references: the number of elements in the
2140 * @backward_references array
2142 * Specifies the list of surfaces used for forward or backward reference in
2143 * advanced deinterlacing mode. The caller is responsible for maintaining
2144 * the associated surfaces live until gst_vaapi_filter_process() completes.
2145 * e.g. by holding an extra reference to the associated #GstVaapiSurfaceProxy.
2147 * Temporal ordering is maintained as follows: the shorter index in
2148 * either array is, the closest the matching surface is relatively to
2149 * the current source surface to process. e.g. surface in
2150 * @forward_references array index 0 represents the immediately
2151 * preceding surface in display order, surface at index 1 is the one
2152 * preceding surface at index 0, etc.
2154 * The video processing filter will only use the recommended number of
2155 * surfaces for backward and forward references.
2157 * Note: the supplied lists of reference surfaces are not sticky. This
2158 * means that they are only valid for the next gst_vaapi_filter_process()
2159 * call, and thus needs to be submitted again for subsequent calls.
2161 * Return value: %TRUE if the operation is supported, %FALSE otherwise.
2164 gst_vaapi_filter_set_deinterlacing_references (GstVaapiFilter * filter,
2165 GstVaapiSurface ** forward_references, guint num_forward_references,
2166 GstVaapiSurface ** backward_references, guint num_backward_references)
2168 g_return_val_if_fail (filter != NULL, FALSE);
2170 deint_refs_clear_all (filter);
2172 if (!deint_refs_set (filter->forward_references, forward_references,
2173 num_forward_references))
2176 if (!deint_refs_set (filter->backward_references, backward_references,
2177 num_backward_references))
2183 * gst_vaapi_filter_set_scaling:
2184 * @filter: a #GstVaapiFilter
2185 * @method: the scaling algorithm (see #GstVaapiScaleMethod)
2187 * Applies scaling algorithm to the video processing pipeline.
2189 * Return value: %TRUE if the operation is supported, %FALSE otherwise.
2192 gst_vaapi_filter_set_scaling (GstVaapiFilter * filter,
2193 GstVaapiScaleMethod method)
2195 g_return_val_if_fail (filter != NULL, FALSE);
2197 filter->scale_method = method;
2201 #ifndef GST_REMOVE_DEPRECATED
2203 * gst_vaapi_filter_set_skintone:
2204 * @filter: a #GstVaapiFilter
2205 * @enhance: %TRUE if enable the skin tone enhancement algorithm
2207 * Applies the skin tone enhancement algorithm.
2209 * Return value: %TRUE if the operation is supported, %FALSE
2213 gst_vaapi_filter_set_skintone (GstVaapiFilter * filter, gboolean enhance)
2215 g_return_val_if_fail (filter != NULL, FALSE);
2217 return op_set_skintone (filter,
2218 find_operation (filter, GST_VAAPI_FILTER_OP_SKINTONE), enhance);
2223 * gst_vaapi_filter_set_skintone_level:
2224 * @filter: a #GstVaapiFilter
2225 * @value: the value if enable the skin tone enhancement algorithm
2227 * Applies the skin tone enhancement algorithm with specifled value.
2229 * Return value: %TRUE if the operation is supported, %FALSE
2233 gst_vaapi_filter_set_skintone_level (GstVaapiFilter * filter, guint value)
2235 g_return_val_if_fail (filter != NULL, FALSE);
2237 return op_set_skintone_level (filter,
2238 find_operation (filter, GST_VAAPI_FILTER_OP_SKINTONE_LEVEL), value);
2242 * gst_vaapi_filter_set_video_direction:
2243 * @filter: a #GstVaapiFilter
2244 * @method: the video direction (see #GstVideoOrientationMethod)
2246 * Applies mirror/rotation to the video processing pipeline.
2248 * Return value: %TRUE if the operation is supported, %FALSE otherwise.
2251 gst_vaapi_filter_set_video_direction (GstVaapiFilter * filter,
2252 GstVideoOrientationMethod method)
2254 g_return_val_if_fail (filter != NULL, FALSE);
2256 #if VA_CHECK_VERSION(1,1,0)
2258 guint32 va_mirror = VA_MIRROR_NONE;
2259 guint32 va_rotation = VA_ROTATION_NONE;
2261 from_GstVideoOrientationMethod (method, &va_mirror, &va_rotation);
2263 if (va_mirror != VA_MIRROR_NONE && !(filter->mirror_flags & va_mirror))
2266 if (va_rotation != VA_ROTATION_NONE
2267 && !(filter->rotation_flags & (1 << va_rotation)))
2274 filter->video_direction = method;
2279 * gst_vaapi_filter_get_video_direction:
2280 * @filter: a #GstVaapiFilter
2282 * Return value: the currently applied video direction (see #GstVideoOrientationMethod)
2284 GstVideoOrientationMethod
2285 gst_vaapi_filter_get_video_direction (GstVaapiFilter * filter)
2287 g_return_val_if_fail (filter != NULL, GST_VIDEO_ORIENTATION_IDENTITY);
2288 return filter->video_direction;
2292 gst_vaapi_filter_get_denoising_level_default (GstVaapiFilter * filter)
2294 OP_RET_DEFAULT_VALUE (float, filter, GST_VAAPI_FILTER_OP_DENOISE);
2298 gst_vaapi_filter_get_sharpening_level_default (GstVaapiFilter * filter)
2300 OP_RET_DEFAULT_VALUE (float, filter, GST_VAAPI_FILTER_OP_SHARPEN);
2304 gst_vaapi_filter_get_hue_default (GstVaapiFilter * filter)
2306 OP_RET_DEFAULT_VALUE (float, filter, GST_VAAPI_FILTER_OP_HUE);
2310 gst_vaapi_filter_get_saturation_default (GstVaapiFilter * filter)
2312 OP_RET_DEFAULT_VALUE (float, filter, GST_VAAPI_FILTER_OP_SATURATION);
2316 gst_vaapi_filter_get_brightness_default (GstVaapiFilter * filter)
2318 OP_RET_DEFAULT_VALUE (float, filter, GST_VAAPI_FILTER_OP_BRIGHTNESS);
2322 gst_vaapi_filter_get_contrast_default (GstVaapiFilter * filter)
2324 OP_RET_DEFAULT_VALUE (float, filter, GST_VAAPI_FILTER_OP_CONTRAST);
2328 gst_vaapi_filter_get_scaling_default (GstVaapiFilter * filter)
2330 OP_RET_DEFAULT_VALUE (enum, filter, GST_VAAPI_FILTER_OP_SCALING);
2333 #ifndef GST_REMOVE_DEPRECATED
2335 gst_vaapi_filter_get_skintone_default (GstVaapiFilter * filter)
2337 OP_RET_DEFAULT_VALUE (boolean, filter, GST_VAAPI_FILTER_OP_SKINTONE);
2342 gst_vaapi_filter_get_skintone_level_default (GstVaapiFilter * filter)
2344 OP_RET_DEFAULT_VALUE (uint, filter, GST_VAAPI_FILTER_OP_SKINTONE_LEVEL);
2347 GstVideoOrientationMethod
2348 gst_vaapi_filter_get_video_direction_default (GstVaapiFilter * filter)
2350 OP_RET_DEFAULT_VALUE (enum, filter, GST_VAAPI_FILTER_OP_VIDEO_DIRECTION);
2354 gst_vaapi_filter_set_colorimetry_unlocked (GstVaapiFilter * filter,
2355 GstVideoColorimetry * input, GstVideoColorimetry * output)
2357 gchar *in_color, *out_color;
2360 filter->input_colorimetry = *input;
2362 gst_video_colorimetry_from_string (&filter->input_colorimetry, NULL);
2365 filter->output_colorimetry = *output;
2367 gst_video_colorimetry_from_string (&filter->output_colorimetry, NULL);
2369 in_color = gst_video_colorimetry_to_string (&filter->input_colorimetry);
2370 GST_DEBUG_OBJECT (filter, " input colorimetry '%s'", in_color);
2372 out_color = gst_video_colorimetry_to_string (&filter->output_colorimetry);
2373 GST_DEBUG_OBJECT (filter, "output colorimetry '%s'", out_color);
2375 if (!gst_vaapi_display_has_driver_quirks (filter->display,
2376 GST_VAAPI_DRIVER_QUIRK_NO_CHECK_VPP_COLOR_STD)) {
2377 VAProcPipelineCaps pipeline_caps = { 0, };
2378 VAProcColorStandardType type;
2381 VAStatus va_status = vaQueryVideoProcPipelineCaps (filter->va_display,
2382 filter->va_context, NULL, 0, &pipeline_caps);
2384 if (!vaapi_check_status (va_status, "vaQueryVideoProcPipelineCaps()"))
2387 type = from_GstVideoColorimetry (&filter->input_colorimetry);
2388 for (i = 0; i < pipeline_caps.num_input_color_standards; i++)
2389 if (type == pipeline_caps.input_color_standards[i])
2391 if ((i == pipeline_caps.num_input_color_standards)
2392 && (type != VAProcColorStandardNone))
2393 GST_WARNING_OBJECT (filter,
2394 "driver does not support '%s' input colorimetry."
2395 " vpp may fail or produce unexpected results.", in_color);
2397 type = from_GstVideoColorimetry (&filter->output_colorimetry);
2398 for (i = 0; i < pipeline_caps.num_output_color_standards; i++)
2399 if (type == pipeline_caps.output_color_standards[i])
2401 if ((i == pipeline_caps.num_output_color_standards)
2402 && (type != VAProcColorStandardNone))
2403 GST_WARNING_OBJECT (filter,
2404 "driver does not support '%s' output colorimetry."
2405 " vpp may fail or produce unexpected results.", out_color);
2407 GST_WARNING_OBJECT (filter,
2408 "driver does not report the supported input/output colorimetry."
2409 " vpp may fail or produce unexpected results.");
2419 gst_vaapi_filter_set_colorimetry (GstVaapiFilter * filter,
2420 GstVideoColorimetry * input, GstVideoColorimetry * output)
2424 g_return_val_if_fail (filter != NULL, FALSE);
2426 GST_VAAPI_DISPLAY_LOCK (filter->display);
2427 result = gst_vaapi_filter_set_colorimetry_unlocked (filter, input, output);
2428 GST_VAAPI_DISPLAY_UNLOCK (filter->display);
2434 * gst_vaapi_filter_set_hdr_tone_map:
2435 * @filter: a #GstVaapiFilter
2436 * @value: %TRUE to enable hdr tone map algorithm
2438 * Applies HDR tone mapping algorithm.
2440 * Return value: %TRUE if the operation is supported, %FALSE otherwise.
2443 gst_vaapi_filter_set_hdr_tone_map (GstVaapiFilter * filter, gboolean value)
2445 g_return_val_if_fail (filter != NULL, FALSE);
2447 return op_set_hdr_tone_map (filter,
2448 find_operation (filter, GST_VAAPI_FILTER_OP_HDR_TONE_MAP), value);
2452 gst_vaapi_filter_set_hdr_tone_map_meta_unlocked (GstVaapiFilter * filter,
2453 GstVideoMasteringDisplayInfo * minfo, GstVideoContentLightLevel * linfo)
2455 #if VA_CHECK_VERSION(1,4,0)
2456 GstVaapiFilterOpData *op_data;
2457 VAProcFilterParameterBufferHDRToneMapping *buf;
2458 VAHdrMetaDataHDR10 *meta = &filter->hdr_meta;
2460 op_data = find_operation (filter, GST_VAAPI_FILTER_OP_HDR_TONE_MAP);
2465 meta->display_primaries_x[0] = minfo->display_primaries[1].x;
2466 meta->display_primaries_x[1] = minfo->display_primaries[2].x;
2467 meta->display_primaries_x[2] = minfo->display_primaries[0].x;
2469 meta->display_primaries_y[0] = minfo->display_primaries[1].y;
2470 meta->display_primaries_y[1] = minfo->display_primaries[2].y;
2471 meta->display_primaries_y[2] = minfo->display_primaries[0].y;
2473 meta->white_point_x = minfo->white_point.x;
2474 meta->white_point_y = minfo->white_point.y;
2476 meta->max_display_mastering_luminance =
2477 minfo->max_display_mastering_luminance;
2478 meta->min_display_mastering_luminance =
2479 minfo->min_display_mastering_luminance;
2481 meta->max_content_light_level = linfo->max_content_light_level;
2482 meta->max_pic_average_light_level = linfo->max_frame_average_light_level;
2484 buf = vaapi_map_buffer (filter->va_display, op_data->va_buffer);
2488 buf->type = op_data->va_type;
2489 buf->data.metadata_type = op_data->va_subtype;
2490 buf->data.metadata = meta;
2491 buf->data.metadata_size = sizeof (meta);
2493 vaapi_unmap_buffer (filter->va_display, op_data->va_buffer, NULL);
2502 * gst_vaapi_filter_set_hdr_tone_map_meta:
2503 * @filter: a #GstVaapiFilter
2504 * @minfo: a #GstVideoMasteringDisplayInfo
2505 * @linfo: a #GstVideoContentLightLevel
2507 * Sets the input HDR meta data used for tone mapping.
2509 * Return value: %TRUE if the operation is supported, %FALSE otherwise.
2512 gst_vaapi_filter_set_hdr_tone_map_meta (GstVaapiFilter * filter,
2513 GstVideoMasteringDisplayInfo * minfo, GstVideoContentLightLevel * linfo)
2515 gboolean status = FALSE;
2517 g_return_val_if_fail (filter != NULL, FALSE);
2518 g_return_val_if_fail (minfo != NULL, FALSE);
2519 g_return_val_if_fail (linfo != NULL, FALSE);
2521 GST_VAAPI_DISPLAY_LOCK (filter->display);
2523 gst_vaapi_filter_set_hdr_tone_map_meta_unlocked (filter, minfo, linfo);
2524 GST_VAAPI_DISPLAY_UNLOCK (filter->display);