msdkvpp: Enable HDR-to-SDR tone mapping

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/5277>
This commit is contained in:
Mengkejiergeli Ba 2023-08-11 15:20:30 +08:00
parent 0ee7ebd17d
commit 887b4095ca
3 changed files with 128 additions and 0 deletions

View file

@ -217561,6 +217561,18 @@
"type": "gboolean",
"writable": true
},
"hdr-tone-mapping": {
"blurb": "Enable HDR to SDR tone mapping",
"conditionally-available": false,
"construct": false,
"construct-only": false,
"controllable": false,
"default": "false",
"mutable": "null",
"readable": true,
"type": "gboolean",
"writable": true
},
"hue": {
"blurb": "The hue of the video",
"conditionally-available": false,

View file

@ -106,6 +106,7 @@ enum
PROP_CROP_RIGHT,
PROP_CROP_TOP,
PROP_CROP_BOTTOM,
PROP_HDR_TONE_MAPPING,
PROP_N,
};
@ -131,6 +132,7 @@ enum
#define PROP_CROP_RIGHT_DEFAULT 0
#define PROP_CROP_TOP_DEFAULT 0
#define PROP_CROP_BOTTOM_DEFAULT 0
#define PROP_HDR_TONE_MAPPING_DEFAULT 0
/* 8 should enough for a normal encoder */
#define SRC_POOL_SIZE_DEFAULT 8
@ -1096,6 +1098,11 @@ ensure_filters (GstMsdkVPP * thiz)
GstVideoInfo *in_vinfo = &thiz->sinkpad_info;
GstVideoInfo *out_vinfo = &thiz->srcpad_info;
mfxExtVideoSignalInfo in_vsi, out_vsi;
mfxExtMasteringDisplayColourVolume mdcv;
mfxExtContentLightLevelInfo cll;
const guint chroma_den = 50000;
const guint luma_den = 10000;
gint tmap = 0;
if (in_vinfo->colorimetry.primaries || in_vinfo->colorimetry.transfer
|| in_vinfo->colorimetry.matrix || in_vinfo->colorimetry.range) {
@ -1114,6 +1121,70 @@ ensure_filters (GstMsdkVPP * thiz)
gst_msdkvpp_add_extra_param (thiz, (mfxExtBuffer *) & in_vsi);
}
if (thiz->hdr_tone_mapping) {
if (thiz->have_mdcv) {
memset (&mdcv, 0, sizeof (mfxExtMasteringDisplayColourVolume));
mdcv.Header.BufferId = MFX_EXTBUFF_MASTERING_DISPLAY_COLOUR_VOLUME_IN;
mdcv.Header.BufferSz = sizeof (mfxExtMasteringDisplayColourVolume);
mdcv.DisplayPrimariesX[0] =
MIN ((thiz->mdcv_info.display_primaries[1].x * chroma_den),
chroma_den);
mdcv.DisplayPrimariesY[0] =
MIN ((thiz->mdcv_info.display_primaries[1].y * chroma_den),
chroma_den);
mdcv.DisplayPrimariesX[1] =
MIN ((thiz->mdcv_info.display_primaries[2].x * chroma_den),
chroma_den);
mdcv.DisplayPrimariesY[1] =
MIN ((thiz->mdcv_info.display_primaries[2].y * chroma_den),
chroma_den);
mdcv.DisplayPrimariesX[2] =
MIN ((thiz->mdcv_info.display_primaries[0].x * chroma_den),
chroma_den);
mdcv.DisplayPrimariesY[2] =
MIN ((thiz->mdcv_info.display_primaries[0].y * chroma_den),
chroma_den);
mdcv.WhitePointX =
MIN ((thiz->mdcv_info.white_point.x * chroma_den), chroma_den);
mdcv.WhitePointY =
MIN ((thiz->mdcv_info.white_point.y * chroma_den), chroma_den);
/* From vpl spec, MaxDisplayMasteringLuminance is in the unit of 1 nits,
* MinDisplayMasteringLuminance is in the unit of 0.0001 nits.
*/
mdcv.MaxDisplayMasteringLuminance =
thiz->mdcv_info.max_display_mastering_luminance;
mdcv.MinDisplayMasteringLuminance =
thiz->mdcv_info.min_display_mastering_luminance * luma_den;
gst_msdkvpp_add_extra_param (thiz, (mfxExtBuffer *) & mdcv);
tmap = 1;
}
if (thiz->have_cll) {
memset (&cll, 0, sizeof (mfxExtContentLightLevelInfo));
cll.Header.BufferId = MFX_EXTBUFF_CONTENT_LIGHT_LEVEL_INFO;
cll.Header.BufferSz = sizeof (mfxExtContentLightLevelInfo);
cll.MaxContentLightLevel =
MIN (thiz->cll_info.max_content_light_level, 65535);
cll.MaxPicAverageLightLevel =
MIN (thiz->cll_info.max_frame_average_light_level, 65535);
gst_msdkvpp_add_extra_param (thiz, (mfxExtBuffer *) & cll);
tmap = 1;
}
}
if (tmap) {
out_vinfo->colorimetry.primaries = GST_VIDEO_COLOR_PRIMARIES_BT709;
out_vinfo->colorimetry.transfer = GST_VIDEO_TRANSFER_BT709;
out_vinfo->colorimetry.range = GST_VIDEO_COLOR_RANGE_16_235;
out_vinfo->colorimetry.matrix = GST_VIDEO_COLOR_MATRIX_BT709;
}
if (out_vinfo->colorimetry.primaries || out_vinfo->colorimetry.transfer
|| out_vinfo->colorimetry.matrix || out_vinfo->colorimetry.range) {
memset (&out_vsi, 0, sizeof (mfxExtVideoSignalInfo));
@ -1339,9 +1410,30 @@ gst_msdkvpp_set_caps (GstBaseTransform * trans, GstCaps * caps,
gst_util_uint64_scale (GST_SECOND, GST_VIDEO_INFO_FPS_D (&out_info),
GST_VIDEO_INFO_FPS_N (&out_info)) : 0;
thiz->have_mdcv = thiz->have_cll = FALSE;
if (gst_video_mastering_display_info_from_caps (&thiz->mdcv_info, caps))
thiz->have_mdcv = TRUE;
if (gst_video_content_light_level_from_caps (&thiz->cll_info, caps))
thiz->have_cll = TRUE;
if (!gst_msdkvpp_initialize (thiz))
return FALSE;
if (!thiz->hdr_tone_mapping) {
if (thiz->have_mdcv) {
if (!gst_video_mastering_display_info_add_to_caps (&thiz->mdcv_info,
out_caps))
GST_WARNING ("Failed to add mastering display info to caps");
}
if (thiz->have_cll) {
if (!gst_video_content_light_level_add_to_caps (&thiz->cll_info,
out_caps))
GST_WARNING ("Failed to add content light level to caps");
}
}
/* set passthrough according to filter operation change */
gst_msdkvpp_set_passthrough (thiz);
@ -1607,6 +1699,9 @@ gst_msdkvpp_set_property (GObject * object, guint prop_id,
case PROP_CROP_BOTTOM:
thiz->crop_bottom = g_value_get_uint (value);
break;
case PROP_HDR_TONE_MAPPING:
thiz->hdr_tone_mapping = g_value_get_boolean (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@ -1682,6 +1777,9 @@ gst_msdkvpp_get_property (GObject * object, guint prop_id,
case PROP_CROP_BOTTOM:
g_value_set_uint (value, thiz->crop_bottom);
break;
case PROP_HDR_TONE_MAPPING:
g_value_set_boolean (value, thiz->hdr_tone_mapping);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@ -1853,6 +1951,16 @@ _msdkvpp_install_properties (GObjectClass * gobject_class)
"Crop Bottom", "Pixels to crop at bottom",
0, G_MAXUINT16, PROP_CROP_BOTTOM_DEFAULT,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
/**
* GstMsdkVPP:hdr-tone-mapping:
*
* Since: 1.24
*/
obj_properties[PROP_HDR_TONE_MAPPING] =
g_param_spec_boolean ("hdr-tone-mapping", "HDR tone mapping",
"Enable HDR to SDR tone mapping (supported from TGL platforms)",
PROP_HDR_TONE_MAPPING_DEFAULT,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
g_object_class_install_properties (gobject_class, PROP_N, obj_properties);
}
@ -1940,6 +2048,7 @@ gst_msdkvpp_init (GTypeInstance * instance, gpointer g_class)
thiz->crop_right = PROP_CROP_RIGHT_DEFAULT;
thiz->crop_top = PROP_CROP_TOP_DEFAULT;
thiz->crop_bottom = PROP_CROP_BOTTOM_DEFAULT;
thiz->hdr_tone_mapping = PROP_HDR_TONE_MAPPING_DEFAULT;
gst_video_info_init (&thiz->sinkpad_info);
gst_video_info_init (&thiz->srcpad_info);

View file

@ -88,6 +88,9 @@ struct _GstMsdkVPP
gboolean add_video_meta;
gboolean need_vpp;
guint flags;
/* To check if sinkcaps have HDR SEIs*/
gboolean have_mdcv;
gboolean have_cll;
/* element properties */
gboolean hardware;
@ -110,6 +113,7 @@ struct _GstMsdkVPP
guint crop_right;
guint crop_top;
guint crop_bottom;
gboolean hdr_tone_mapping;
GstClockTime buffer_duration;
@ -124,6 +128,9 @@ struct _GstMsdkVPP
mfxExtVPPScaling mfx_scaling;
mfxExtVPPFrameRateConversion mfx_frc;
GstVideoMasteringDisplayInfo mdcv_info;
GstVideoContentLightLevel cll_info;
/* Extended buffers */
mfxExtBuffer *extra_params[MAX_EXTRA_PARAMS];
guint num_extra_params;