From be1f66a4911caeeb022cb003160aa851df2a5ade Mon Sep 17 00:00:00 2001 From: Haihao Xiang Date: Wed, 17 Mar 2021 14:38:40 +0800 Subject: [PATCH] msdkenc{h264,h265}: add intra-refresh-type property The SDK allows user to specify the intra refresh type which can improve error resilience without significant impact on encoded bitstream size caused by I frames [1] [1] https://github.com/Intel-Media-SDK/MediaSDK/blob/master/doc/mediasdk-man.md#mfxextcodingoption2 Part-of: --- sys/msdk/gstmsdkh264enc.c | 17 +++++++++++++++++ sys/msdk/gstmsdkh264enc.h | 1 + sys/msdk/gstmsdkh265enc.c | 19 +++++++++++++++++++ sys/msdk/gstmsdkh265enc.h | 1 + sys/msdk/msdk-enums.c | 20 ++++++++++++++++++++ sys/msdk/msdk-enums.h | 3 +++ 6 files changed, 61 insertions(+) diff --git a/sys/msdk/gstmsdkh264enc.c b/sys/msdk/gstmsdkh264enc.c index 6fde9e98a1..d01860f173 100644 --- a/sys/msdk/gstmsdkh264enc.c +++ b/sys/msdk/gstmsdkh264enc.c @@ -57,6 +57,7 @@ enum PROP_P_PYRAMID, PROP_MIN_QP, PROP_MAX_QP, + PROP_INTRA_REFRESH_TYPE, }; enum @@ -76,6 +77,7 @@ enum #define PROP_P_PYRAMID_DEFAULT FALSE #define PROP_MIN_QP_DEFAULT 0 #define PROP_MAX_QP_DEFAULT 0 +#define PROP_INTRA_REFRESH_TYPE_DEFAULT MFX_REFRESH_NO static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src", GST_PAD_SRC, @@ -386,6 +388,7 @@ gst_msdkh264enc_configure (GstMsdkEnc * encoder) thiz->min_qp; encoder->option2.MaxQPI = encoder->option2.MaxQPP = encoder->option2.MaxQPB = thiz->max_qp; + encoder->option2.IntRefType = thiz->intra_refresh_type; if (encoder->rate_control == MFX_RATECONTROL_LA || encoder->rate_control == MFX_RATECONTROL_LA_HRD || @@ -586,6 +589,9 @@ gst_msdkh264enc_set_property (GObject * object, guint prop_id, case PROP_MAX_QP: thiz->max_qp = g_value_get_uint (value); break; + case PROP_INTRA_REFRESH_TYPE: + thiz->intra_refresh_type = g_value_get_enum (value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -640,6 +646,9 @@ gst_msdkh264enc_get_property (GObject * object, guint prop_id, GValue * value, case PROP_MAX_QP: g_value_set_uint (value, thiz->max_qp); break; + case PROP_INTRA_REFRESH_TYPE: + g_value_set_enum (value, thiz->intra_refresh_type); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -758,6 +767,13 @@ gst_msdkh264enc_class_init (GstMsdkH264EncClass * klass) 0, 51, PROP_MAX_QP_DEFAULT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + g_object_class_install_property (gobject_class, PROP_INTRA_REFRESH_TYPE, + g_param_spec_enum ("intra-refresh-type", "Intra refresh type", + "Set intra refresh type", + gst_msdkenc_intra_refresh_type_get_type (), + PROP_INTRA_REFRESH_TYPE_DEFAULT, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + gst_element_class_set_static_metadata (element_class, "Intel MSDK H264 encoder", "Codec/Encoder/Video/Hardware", "H264 video encoder based on Intel Media SDK", @@ -779,4 +795,5 @@ gst_msdkh264enc_init (GstMsdkH264Enc * thiz) thiz->p_pyramid = PROP_P_PYRAMID_DEFAULT; thiz->min_qp = PROP_MIN_QP_DEFAULT; thiz->max_qp = PROP_MAX_QP_DEFAULT; + thiz->intra_refresh_type = PROP_INTRA_REFRESH_TYPE_DEFAULT; } diff --git a/sys/msdk/gstmsdkh264enc.h b/sys/msdk/gstmsdkh264enc.h index e6e0badbe6..3cffa0027e 100644 --- a/sys/msdk/gstmsdkh264enc.h +++ b/sys/msdk/gstmsdkh264enc.h @@ -74,6 +74,7 @@ struct _GstMsdkH264Enc guint p_pyramid; guint min_qp; guint max_qp; + guint intra_refresh_type; GstH264NalParser *parser; GArray *cc_sei_array; diff --git a/sys/msdk/gstmsdkh265enc.c b/sys/msdk/gstmsdkh265enc.c index 3c0f15d182..82bcd10df2 100644 --- a/sys/msdk/gstmsdkh265enc.c +++ b/sys/msdk/gstmsdkh265enc.c @@ -56,6 +56,7 @@ enum PROP_P_PYRAMID, PROP_MIN_QP, PROP_MAX_QP, + PROP_INTRA_REFRESH_TYPE, }; enum @@ -74,6 +75,7 @@ enum #define PROP_P_PYRAMID_DEFAULT FALSE #define PROP_MIN_QP_DEFAULT 0 #define PROP_MAX_QP_DEFAULT 0 +#define PROP_INTRA_REFRESH_TYPE_DEFAULT MFX_REFRESH_NO #define RAW_FORMATS "NV12, I420, YV12, YUY2, UYVY, BGRA, P010_10LE, VUYA" #define PROFILES "main, main-10, main-444" @@ -351,6 +353,7 @@ gst_msdkh265enc_configure (GstMsdkEnc * encoder) h265enc->min_qp; encoder->option2.MaxQPI = encoder->option2.MaxQPP = encoder->option2.MaxQPB = h265enc->max_qp; + encoder->option2.IntRefType = h265enc->intra_refresh_type; #if (MFX_VERSION >= 1026) if (h265enc->transform_skip != MFX_CODINGOPTION_UNKNOWN) { @@ -574,6 +577,10 @@ gst_msdkh265enc_set_property (GObject * object, guint prop_id, thiz->max_qp = g_value_get_uint (value); break; + case PROP_INTRA_REFRESH_TYPE: + thiz->intra_refresh_type = g_value_get_enum (value); + break; + default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -634,6 +641,10 @@ gst_msdkh265enc_get_property (GObject * object, guint prop_id, GValue * value, g_value_set_uint (value, thiz->max_qp); break; + case PROP_INTRA_REFRESH_TYPE: + g_value_set_enum (value, thiz->intra_refresh_type); + break; + default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -781,6 +792,13 @@ gst_msdkh265enc_class_init (GstMsdkH265EncClass * klass) 0, 51, PROP_MAX_QP_DEFAULT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + g_object_class_install_property (gobject_class, PROP_INTRA_REFRESH_TYPE, + g_param_spec_enum ("intra-refresh-type", "Intra refresh type", + "Set intra refresh type", + gst_msdkenc_intra_refresh_type_get_type (), + PROP_INTRA_REFRESH_TYPE_DEFAULT, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + gst_element_class_set_static_metadata (element_class, "Intel MSDK H265 encoder", "Codec/Encoder/Video/Hardware", @@ -805,5 +823,6 @@ gst_msdkh265enc_init (GstMsdkH265Enc * thiz) thiz->p_pyramid = PROP_P_PYRAMID_DEFAULT; thiz->min_qp = PROP_MIN_QP_DEFAULT; thiz->max_qp = PROP_MAX_QP_DEFAULT; + thiz->intra_refresh_type = PROP_INTRA_REFRESH_TYPE_DEFAULT; msdk_enc->num_extra_frames = 1; } diff --git a/sys/msdk/gstmsdkh265enc.h b/sys/msdk/gstmsdkh265enc.h index ea58590667..fa72459aa0 100644 --- a/sys/msdk/gstmsdkh265enc.h +++ b/sys/msdk/gstmsdkh265enc.h @@ -67,6 +67,7 @@ struct _GstMsdkH265Enc guint p_pyramid; guint min_qp; guint max_qp; + guint intra_refresh_type; mfxExtHEVCTiles ext_tiles; /* roi[0] for current ROI and roi[1] for previous ROI */ diff --git a/sys/msdk/msdk-enums.c b/sys/msdk/msdk-enums.c index 73064228da..edd6f2eabe 100644 --- a/sys/msdk/msdk-enums.c +++ b/sys/msdk/msdk-enums.c @@ -215,6 +215,26 @@ gst_msdkenc_transform_skip_get_type (void) return type; } +GType +gst_msdkenc_intra_refresh_type_get_type (void) +{ + static GType type = 0; + + static const GEnumValue values[] = { + {MFX_REFRESH_NO, "No (default)", "no"}, + {MFX_REFRESH_VERTICAL, "Vertical", "vertical"}, + {MFX_REFRESH_HORIZONTAL, "Horizontal ", "horizontal"}, + {MFX_REFRESH_SLICE, "Slice ", "slice"}, + {0, NULL, NULL} + }; + + if (!type) { + type = g_enum_register_static ("GstMsdkEncIntraRefreshType", values); + } + + return type; +} + /*========= MSDK VPP Enums =========================*/ #ifndef GST_REMOVE_DEPRECATED diff --git a/sys/msdk/msdk-enums.h b/sys/msdk/msdk-enums.h index 26c990315c..56027a90ee 100644 --- a/sys/msdk/msdk-enums.h +++ b/sys/msdk/msdk-enums.h @@ -104,5 +104,8 @@ gst_msdkvpp_frc_algorithm_get_type (void); GType gst_msdkenc_transform_skip_get_type (void); +GType +gst_msdkenc_intra_refresh_type_get_type (void); + G_END_DECLS #endif