vapostproc: Process HDR caps
This patch adds a new parameter: hdr-tone-mapping (same as vaapipostproc), if the HDR capabilites are availabe in driver, and it's disabled by default. If hdr-tone-mapping is enabled then HDR fields in sink caps are processed in frames from HDR to SDR, removing those hdr fields in source pad caps too. hdr-tone-mapping is not enabled if a color conversion is also requested, since it fails to process in the iHD driver, so far. Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/1258>
This commit is contained in:
parent
0e7dade55a
commit
4be3413fec
@ -676,6 +676,15 @@ gst_va_filter_install_properties (GstVaFilter * self, GObjectClass * klass)
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case VAProcFilterHighDynamicRangeToneMapping:{
|
||||||
|
const VAProcFilterCapHighDynamicRange *caps = &filter->caps.hdr;
|
||||||
|
if (caps->metadata_type == VAProcHighDynamicRangeMetadataHDR10
|
||||||
|
&& (caps->caps_flag & VA_TONE_MAPPING_HDR_TO_SDR)) {
|
||||||
|
g_object_class_install_property (klass, GST_VA_FILTER_PROP_HDR,
|
||||||
|
g_param_spec_boolean ("hdr-tone-mapping", "HDR tone mapping",
|
||||||
|
"Enable HDR to SDR tone mapping", FALSE, common_flags));
|
||||||
|
}
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1608,6 +1617,8 @@ _create_pipeline_buffer (GstVaFilter * self, GstVaSample * src,
|
|||||||
.output_surface_flag = dst->flags,
|
.output_surface_flag = dst->flags,
|
||||||
.input_color_properties = self->input_color_properties,
|
.input_color_properties = self->input_color_properties,
|
||||||
.output_color_properties = self->output_color_properties,
|
.output_color_properties = self->output_color_properties,
|
||||||
|
/* output to SDR */
|
||||||
|
.output_hdr_metadata = NULL,
|
||||||
};
|
};
|
||||||
/* *INDENT-ON* */
|
/* *INDENT-ON* */
|
||||||
|
|
||||||
|
@ -53,6 +53,7 @@ enum {
|
|||||||
GST_VA_FILTER_PROP_DISABLE_PASSTHROUGH,
|
GST_VA_FILTER_PROP_DISABLE_PASSTHROUGH,
|
||||||
GST_VA_FILTER_PROP_DEINTERLACE_METHOD,
|
GST_VA_FILTER_PROP_DEINTERLACE_METHOD,
|
||||||
GST_VA_FILTER_PROP_ADD_BORDERS,
|
GST_VA_FILTER_PROP_ADD_BORDERS,
|
||||||
|
GST_VA_FILTER_PROP_HDR,
|
||||||
GST_VA_FILTER_PROP_LAST
|
GST_VA_FILTER_PROP_LAST
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -56,11 +56,6 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* ToDo:
|
|
||||||
*
|
|
||||||
* + HDR tone mapping
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
#endif
|
||||||
@ -121,6 +116,10 @@ struct _GstVaVpp
|
|||||||
gint borders_h;
|
gint borders_h;
|
||||||
gint borders_w;
|
gint borders_w;
|
||||||
|
|
||||||
|
gboolean hdr_mapping;
|
||||||
|
gboolean has_hdr_meta;
|
||||||
|
VAHdrMetaDataHDR10 hdr_meta;
|
||||||
|
|
||||||
GList *channels;
|
GList *channels;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -304,6 +303,10 @@ gst_va_vpp_set_property (GObject * object, guint prop_id,
|
|||||||
case GST_VA_FILTER_PROP_ADD_BORDERS:
|
case GST_VA_FILTER_PROP_ADD_BORDERS:
|
||||||
self->add_borders = g_value_get_boolean (value);
|
self->add_borders = g_value_get_boolean (value);
|
||||||
break;
|
break;
|
||||||
|
case GST_VA_FILTER_PROP_HDR:
|
||||||
|
self->hdr_mapping = g_value_get_boolean (value);
|
||||||
|
g_atomic_int_set (&self->rebuild_filters, TRUE);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
break;
|
break;
|
||||||
@ -365,6 +368,9 @@ gst_va_vpp_get_property (GObject * object, guint prop_id, GValue * value,
|
|||||||
case GST_VA_FILTER_PROP_ADD_BORDERS:
|
case GST_VA_FILTER_PROP_ADD_BORDERS:
|
||||||
g_value_set_boolean (value, self->add_borders);
|
g_value_set_boolean (value, self->add_borders);
|
||||||
break;
|
break;
|
||||||
|
case GST_VA_FILTER_PROP_HDR:
|
||||||
|
g_value_set_boolean (value, self->hdr_mapping);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
break;
|
break;
|
||||||
@ -393,6 +399,47 @@ gst_va_vpp_update_properties (GstVaBaseTransform * btrans)
|
|||||||
_update_properties_unlocked (self);
|
_update_properties_unlocked (self);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_set_hdr_metadata (GstVaVpp * self, GstCaps * caps)
|
||||||
|
{
|
||||||
|
GstVideoMasteringDisplayInfo mdinfo;
|
||||||
|
GstVideoContentLightLevel llevel;
|
||||||
|
|
||||||
|
self->has_hdr_meta = FALSE;
|
||||||
|
|
||||||
|
if (gst_video_mastering_display_info_from_caps (&mdinfo, caps)) {
|
||||||
|
self->hdr_meta.display_primaries_x[0] = mdinfo.display_primaries[1].x;
|
||||||
|
self->hdr_meta.display_primaries_x[1] = mdinfo.display_primaries[2].x;
|
||||||
|
self->hdr_meta.display_primaries_x[2] = mdinfo.display_primaries[0].x;
|
||||||
|
|
||||||
|
self->hdr_meta.display_primaries_y[0] = mdinfo.display_primaries[1].y;
|
||||||
|
self->hdr_meta.display_primaries_y[1] = mdinfo.display_primaries[2].y;
|
||||||
|
self->hdr_meta.display_primaries_y[2] = mdinfo.display_primaries[0].y;
|
||||||
|
|
||||||
|
self->hdr_meta.white_point_x = mdinfo.white_point.x;
|
||||||
|
self->hdr_meta.white_point_y = mdinfo.white_point.y;
|
||||||
|
|
||||||
|
self->hdr_meta.max_display_mastering_luminance =
|
||||||
|
mdinfo.max_display_mastering_luminance;
|
||||||
|
self->hdr_meta.min_display_mastering_luminance =
|
||||||
|
mdinfo.min_display_mastering_luminance;
|
||||||
|
|
||||||
|
self->has_hdr_meta = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (gst_video_content_light_level_from_caps (&llevel, caps)) {
|
||||||
|
self->hdr_meta.max_content_light_level = llevel.max_content_light_level;
|
||||||
|
self->hdr_meta.max_pic_average_light_level =
|
||||||
|
llevel.max_frame_average_light_level;
|
||||||
|
|
||||||
|
self->has_hdr_meta = TRUE;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* rebuild filters only if hdr mapping is enabled */
|
||||||
|
g_atomic_int_set (&self->rebuild_filters, self->hdr_mapping);
|
||||||
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_va_vpp_set_info (GstVaBaseTransform * btrans, GstCaps * incaps,
|
gst_va_vpp_set_info (GstVaBaseTransform * btrans, GstCaps * incaps,
|
||||||
GstVideoInfo * in_info, GstCaps * outcaps, GstVideoInfo * out_info)
|
GstVideoInfo * in_info, GstCaps * outcaps, GstVideoInfo * out_info)
|
||||||
@ -484,6 +531,7 @@ gst_va_vpp_set_info (GstVaBaseTransform * btrans, GstCaps * incaps,
|
|||||||
self->op_flags &= ~VPP_CONVERT_FEATURE;
|
self->op_flags &= ~VPP_CONVERT_FEATURE;
|
||||||
|
|
||||||
if (gst_va_filter_set_video_info (btrans->filter, in_info, out_info)) {
|
if (gst_va_filter_set_video_info (btrans->filter, in_info, out_info)) {
|
||||||
|
_set_hdr_metadata (self, incaps);
|
||||||
gst_va_vpp_update_passthrough (self, FALSE);
|
gst_va_vpp_update_passthrough (self, FALSE);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
@ -611,13 +659,50 @@ _add_filter_cb_buffer (GstVaVpp * self,
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline gboolean
|
||||||
|
_add_filter_hdr_buffer (GstVaVpp * self,
|
||||||
|
const VAProcFilterCapHighDynamicRange * caps)
|
||||||
|
{
|
||||||
|
GstVaBaseTransform *btrans = GST_VA_BASE_TRANSFORM (self);
|
||||||
|
/* *INDENT-OFF* */
|
||||||
|
VAProcFilterParameterBufferHDRToneMapping params = {
|
||||||
|
.type = VAProcFilterHighDynamicRangeToneMapping,
|
||||||
|
.data = {
|
||||||
|
.metadata_type = VAProcHighDynamicRangeMetadataHDR10,
|
||||||
|
.metadata = &self->hdr_meta,
|
||||||
|
.metadata_size = sizeof (self->hdr_meta),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
/* *INDENT-ON* */
|
||||||
|
|
||||||
|
/* if not has hdr meta, it may try later again */
|
||||||
|
if (!(self->has_hdr_meta && self->hdr_mapping))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (!(caps && caps->metadata_type == VAProcHighDynamicRangeMetadataHDR10
|
||||||
|
&& (caps->caps_flag & VA_TONE_MAPPING_HDR_TO_SDR)))
|
||||||
|
goto bail;
|
||||||
|
|
||||||
|
if (self->op_flags & VPP_CONVERT_FORMAT) {
|
||||||
|
GST_WARNING_OBJECT (self, "Cannot apply HDR with color conversion");
|
||||||
|
goto bail;
|
||||||
|
}
|
||||||
|
|
||||||
|
return gst_va_filter_add_filter_buffer (btrans->filter, ¶ms,
|
||||||
|
sizeof (params), 1);
|
||||||
|
|
||||||
|
bail:
|
||||||
|
self->hdr_mapping = FALSE;
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_build_filters (GstVaVpp * self)
|
_build_filters (GstVaVpp * self)
|
||||||
{
|
{
|
||||||
GstVaBaseTransform *btrans = GST_VA_BASE_TRANSFORM (self);
|
GstVaBaseTransform *btrans = GST_VA_BASE_TRANSFORM (self);
|
||||||
static const VAProcFilterType filter_types[] = { VAProcFilterNoiseReduction,
|
static const VAProcFilterType filter_types[] = { VAProcFilterNoiseReduction,
|
||||||
VAProcFilterSharpening, VAProcFilterSkinToneEnhancement,
|
VAProcFilterSharpening, VAProcFilterSkinToneEnhancement,
|
||||||
VAProcFilterColorBalance,
|
VAProcFilterColorBalance, VAProcFilterHighDynamicRangeToneMapping,
|
||||||
};
|
};
|
||||||
guint i, num_caps;
|
guint i, num_caps;
|
||||||
gboolean apply = FALSE;
|
gboolean apply = FALSE;
|
||||||
@ -641,6 +726,8 @@ _build_filters (GstVaVpp * self)
|
|||||||
case VAProcFilterColorBalance:
|
case VAProcFilterColorBalance:
|
||||||
apply |= _add_filter_cb_buffer (self, caps, num_caps);
|
apply |= _add_filter_cb_buffer (self, caps, num_caps);
|
||||||
break;
|
break;
|
||||||
|
case VAProcFilterHighDynamicRangeToneMapping:
|
||||||
|
apply |= _add_filter_hdr_buffer (self, caps);
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1705,6 +1792,15 @@ copy_misc_fields_from_input (GstCaps * in_caps, GstCaps * out_caps)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
remove_hdr_fields (GstCaps * caps)
|
||||||
|
{
|
||||||
|
GstStructure *s = gst_caps_get_structure (caps, 0);
|
||||||
|
|
||||||
|
gst_structure_remove_fields (s, "mastering-display-info",
|
||||||
|
"content-light-level", "hdr-format", NULL);
|
||||||
|
}
|
||||||
|
|
||||||
static GstCaps *
|
static GstCaps *
|
||||||
gst_va_vpp_fixate_caps (GstBaseTransform * trans, GstPadDirection direction,
|
gst_va_vpp_fixate_caps (GstBaseTransform * trans, GstPadDirection direction,
|
||||||
GstCaps * caps, GstCaps * othercaps)
|
GstCaps * caps, GstCaps * othercaps)
|
||||||
@ -1737,6 +1833,8 @@ gst_va_vpp_fixate_caps (GstBaseTransform * trans, GstPadDirection direction,
|
|||||||
} else {
|
} else {
|
||||||
/* Try and preserve input colorimetry / chroma information */
|
/* Try and preserve input colorimetry / chroma information */
|
||||||
transfer_colorimetry_from_input (self, caps, result);
|
transfer_colorimetry_from_input (self, caps, result);
|
||||||
|
if (self->hdr_mapping)
|
||||||
|
remove_hdr_fields (result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2066,6 +2164,13 @@ gst_va_vpp_init (GTypeInstance * instance, gpointer g_class)
|
|||||||
_create_colorbalance_channel (self, "SATURATION");
|
_create_colorbalance_channel (self, "SATURATION");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* HDR tone mapping */
|
||||||
|
pspec = g_object_class_find_property (g_class, "hdr-tone-mapping");
|
||||||
|
if (pspec) {
|
||||||
|
self->hdr_mapping =
|
||||||
|
g_value_get_boolean (g_param_spec_get_default_value (pspec));
|
||||||
|
}
|
||||||
|
|
||||||
/* enable QoS */
|
/* enable QoS */
|
||||||
gst_base_transform_set_qos_enabled (GST_BASE_TRANSFORM (instance), TRUE);
|
gst_base_transform_set_qos_enabled (GST_BASE_TRANSFORM (instance), TRUE);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user