msdkenc: Enable LowDelayBrc and MaxFrameSize for I/P frame

Enable these features for accurate bitrate control.
Feature introduction of LowDelayBRC, MaxFrameSizeI and MaxFrameSizeP could be found here:
https://github.com/Intel-Media-SDK/MediaSDK/blob/master/doc/mediasdk-man.md

Signed-off-by: Fan F He <fan.f.he@intel.com>
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/2742>
This commit is contained in:
Fan F He 2022-04-29 19:27:16 +08:00 committed by HeFan2017
parent ee289a65ce
commit 6fe35ad59d
7 changed files with 90 additions and 0 deletions

View file

@ -113,7 +113,10 @@ static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink",
#define PROP_RC_LOOKAHEAD_DEPTH_DEFAULT 10
#define PROP_MAX_VBV_BITRATE_DEFAULT 0
#define PROP_MAX_FRAME_SIZE_DEFAULT 0
#define PROP_MAX_FRAME_SIZE_I_DEFAULT 0
#define PROP_MAX_FRAME_SIZE_P_DEFAULT 0
#define PROP_MBBRC_DEFAULT MFX_CODINGOPTION_OFF
#define PROP_LOWDELAY_BRC_DEFAULT MFX_CODINGOPTION_OFF
#define PROP_ADAPTIVE_I_DEFAULT MFX_CODINGOPTION_OFF
#define PROP_ADAPTIVE_B_DEFAULT MFX_CODINGOPTION_OFF
@ -222,7 +225,15 @@ ensure_bitrate_control (GstMsdkEnc * thiz)
break;
case MFX_RATECONTROL_VBR:
thiz->enable_extopt3 = TRUE;
option2->MaxFrameSize = thiz->max_frame_size * 1000;
if (thiz->max_frame_size_i > 0)
option3->MaxFrameSizeI = thiz->max_frame_size_i * 1000;
if (thiz->max_frame_size_p > 0)
option3->MaxFrameSizeP = thiz->max_frame_size_p * 1000;
if (thiz->lowdelay_brc != MFX_CODINGOPTION_UNKNOWN) {
option3->LowDelayBRC = thiz->lowdelay_brc;
}
break;
case MFX_RATECONTROL_VCM:
@ -2282,6 +2293,8 @@ gst_msdkenc_init (GstMsdkEnc * thiz)
thiz->rate_control = PROP_RATE_CONTROL_DEFAULT;
thiz->bitrate = PROP_BITRATE_DEFAULT;
thiz->max_frame_size = PROP_MAX_FRAME_SIZE_DEFAULT;
thiz->max_frame_size_i = PROP_MAX_FRAME_SIZE_I_DEFAULT;
thiz->max_frame_size_p = PROP_MAX_FRAME_SIZE_P_DEFAULT;
thiz->max_vbv_bitrate = PROP_MAX_VBV_BITRATE_DEFAULT;
thiz->accuracy = PROP_AVBR_ACCURACY_DEFAULT;
thiz->convergence = PROP_AVBR_ACCURACY_DEFAULT;
@ -2295,6 +2308,7 @@ gst_msdkenc_init (GstMsdkEnc * thiz)
thiz->b_frames = PROP_B_FRAMES_DEFAULT;
thiz->num_slices = PROP_NUM_SLICES_DEFAULT;
thiz->mbbrc = PROP_MBBRC_DEFAULT;
thiz->lowdelay_brc = PROP_LOWDELAY_BRC_DEFAULT;
thiz->adaptive_i = PROP_ADAPTIVE_I_DEFAULT;
thiz->adaptive_b = PROP_ADAPTIVE_B_DEFAULT;
@ -2351,6 +2365,12 @@ gst_msdkenc_set_common_property (GObject * object, guint prop_id,
case GST_MSDKENC_PROP_MAX_FRAME_SIZE:
thiz->max_frame_size = g_value_get_uint (value);
break;
case GST_MSDKENC_PROP_MAX_FRAME_SIZE_I:
thiz->max_frame_size_i = g_value_get_uint (value);
break;
case GST_MSDKENC_PROP_MAX_FRAME_SIZE_P:
thiz->max_frame_size_p = g_value_get_uint (value);
break;
case GST_MSDKENC_PROP_MAX_VBV_BITRATE:
thiz->max_vbv_bitrate = g_value_get_uint (value);
break;
@ -2390,6 +2410,9 @@ gst_msdkenc_set_common_property (GObject * object, guint prop_id,
case GST_MSDKENC_PROP_MBBRC:
thiz->mbbrc = g_value_get_enum (value);
break;
case GST_MSDKENC_PROP_LOWDELAY_BRC:
thiz->lowdelay_brc = g_value_get_enum (value);
break;
case GST_MSDKENC_PROP_ADAPTIVE_I:
thiz->adaptive_i = g_value_get_enum (value);
break;
@ -2454,6 +2477,12 @@ gst_msdkenc_get_common_property (GObject * object, guint prop_id,
case GST_MSDKENC_PROP_MAX_FRAME_SIZE:
g_value_set_uint (value, thiz->max_frame_size);
break;
case GST_MSDKENC_PROP_MAX_FRAME_SIZE_I:
g_value_set_uint (value, thiz->max_frame_size_i);
break;
case GST_MSDKENC_PROP_MAX_FRAME_SIZE_P:
g_value_set_uint (value, thiz->max_frame_size_p);
break;
case GST_MSDKENC_PROP_MAX_VBV_BITRATE:
g_value_set_uint (value, thiz->max_vbv_bitrate);
break;
@ -2493,6 +2522,9 @@ gst_msdkenc_get_common_property (GObject * object, guint prop_id,
case GST_MSDKENC_PROP_MBBRC:
g_value_set_enum (value, thiz->mbbrc);
break;
case GST_MSDKENC_PROP_LOWDELAY_BRC:
g_value_set_enum (value, thiz->lowdelay_brc);
break;
case GST_MSDKENC_PROP_ADAPTIVE_I:
g_value_set_enum (value, thiz->adaptive_i);
break;
@ -2558,6 +2590,18 @@ gst_msdkenc_install_common_properties (GstMsdkEncClass * klass)
0, G_MAXUINT16, PROP_MAX_FRAME_SIZE_DEFAULT,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
obj_properties[GST_MSDKENC_PROP_MAX_FRAME_SIZE_I] =
g_param_spec_uint ("max-frame-size-i", "Max Frame Size for I frame",
"Maximum possible size (in kbyte) of I frames (0: auto-calculate)",
0, G_MAXUINT16, PROP_MAX_FRAME_SIZE_I_DEFAULT,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
obj_properties[GST_MSDKENC_PROP_MAX_FRAME_SIZE_P] =
g_param_spec_uint ("max-frame-size-p", "Max Frame Size for P frame",
"Maximum possible size (in kbyte) of P frames (0: auto-calculate)",
0, G_MAXUINT16, PROP_MAX_FRAME_SIZE_P_DEFAULT,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
/* Set the same upper bound with bitrate */
obj_properties[GST_MSDKENC_PROP_MAX_VBV_BITRATE] =
g_param_spec_uint ("max-vbv-bitrate", "Max VBV Bitrate",
@ -2637,6 +2681,12 @@ gst_msdkenc_install_common_properties (GstMsdkEncClass * klass)
gst_msdkenc_mbbrc_get_type (),
PROP_MBBRC_DEFAULT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
obj_properties[GST_MSDKENC_PROP_LOWDELAY_BRC] =
g_param_spec_enum ("lowdelay-brc", "Low delay bitrate control",
"Bitrate control for low-delay user scenarios",
gst_msdkenc_lowdelay_brc_get_type (),
PROP_LOWDELAY_BRC_DEFAULT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
obj_properties[GST_MSDKENC_PROP_ADAPTIVE_I] =
g_param_spec_enum ("i-adapt", "Adaptive I-Frame Insertion",
"Adaptive I-Frame Insertion control",

View file

@ -84,6 +84,9 @@ enum
GST_MSDKENC_PROP_ADAPTIVE_I,
GST_MSDKENC_PROP_ADAPTIVE_B,
GST_MSDKENC_PROP_EXT_CODING_PROPS,
GST_MSDKENC_PROP_LOWDELAY_BRC,
GST_MSDKENC_PROP_MAX_FRAME_SIZE_I,
GST_MSDKENC_PROP_MAX_FRAME_SIZE_P,
GST_MSDKENC_PROP_MAX,
};
@ -159,6 +162,9 @@ struct _GstMsdkEnc
gint16 mbbrc;
gint16 adaptive_i;
gint16 adaptive_b;
guint max_frame_size_i;
guint max_frame_size_p;
gint16 lowdelay_brc;
GstStructure *ext_coding_props;

View file

@ -404,6 +404,10 @@ gst_msdkh264enc_configure (GstMsdkEnc * encoder)
(thiz->cabac ? MFX_CODINGOPTION_OFF : MFX_CODINGOPTION_ON);
}
if (encoder->option3.LowDelayBRC == MFX_CODINGOPTION_ON) {
thiz->option.NalHrdConformance = MFX_CODINGOPTION_OFF;
}
gst_msdkenc_add_extra_param (encoder, (mfxExtBuffer *) & thiz->option);
encoder->option2.Trellis = thiz->trellis ? thiz->trellis : MFX_TRELLIS_OFF;

View file

@ -539,6 +539,13 @@ gst_msdkh265enc_configure (GstMsdkEnc * encoder)
encoder->enable_extopt3 = TRUE;
}
if (encoder->option3.LowDelayBRC == MFX_CODINGOPTION_ON) {
h265enc->option.Header.BufferId = MFX_EXTBUFF_CODING_OPTION;
h265enc->option.Header.BufferSz = sizeof (h265enc->option);
h265enc->option.NalHrdConformance = MFX_CODINGOPTION_OFF;
gst_msdkenc_add_extra_param (encoder, (mfxExtBuffer *) & h265enc->option);
}
gst_msdkenc_ensure_extended_coding_options (encoder);
if (h265enc->num_tile_rows > 1 || h265enc->num_tile_cols > 1) {

View file

@ -75,6 +75,8 @@ struct _GstMsdkH265Enc
mfxExtHEVCTiles ext_tiles;
mfxExtHEVCParam ext_param;
mfxExtCodingOption option;
/* roi[0] for current ROI and roi[1] for previous ROI */
mfxExtEncoderROI roi[2];

View file

@ -140,6 +140,24 @@ gst_msdkenc_mbbrc_get_type (void)
return type;
}
GType
gst_msdkenc_lowdelay_brc_get_type (void)
{
static GType type = 0;
static const GEnumValue values[] = {
{MFX_CODINGOPTION_UNKNOWN, "SDK decides what to do", "auto"},
{MFX_CODINGOPTION_OFF, "Disable LowDelay bit rate control", "off"},
{MFX_CODINGOPTION_ON, "Enable LowDelay bit rate control ", "on"},
{0, NULL, NULL}
};
if (!type) {
type = g_enum_register_static ("GstMsdkEncLowDelayBitrateControl", values);
}
return type;
}
GType
gst_msdkenc_adaptive_i_get_type (void)
{

View file

@ -63,6 +63,9 @@ gst_msdkenc_rc_lookahead_ds_get_type (void);
GType
gst_msdkenc_mbbrc_get_type (void);
GType
gst_msdkenc_lowdelay_brc_get_type (void);
GType
gst_msdkenc_adaptive_i_get_type (void);