msdkenc: Enable LowDelayBrc and MaxFrameSize for I/P frame
authorFan F He <fan.f.he@intel.com>
Fri, 29 Apr 2022 11:27:16 +0000 (19:27 +0800)
committerHeFan2017 <hefangnm@gmail.com>
Wed, 20 Jul 2022 07:10:19 +0000 (07:10 +0000)
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>

subprojects/gst-plugins-bad/sys/msdk/gstmsdkenc.c
subprojects/gst-plugins-bad/sys/msdk/gstmsdkenc.h
subprojects/gst-plugins-bad/sys/msdk/gstmsdkh264enc.c
subprojects/gst-plugins-bad/sys/msdk/gstmsdkh265enc.c
subprojects/gst-plugins-bad/sys/msdk/gstmsdkh265enc.h
subprojects/gst-plugins-bad/sys/msdk/msdk-enums.c
subprojects/gst-plugins-bad/sys/msdk/msdk-enums.h

index b7bee43..80b5c59 100644 (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",
index e16f4e0..705a6b0 100644 (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;
 
index 713ca8f..4dd30e6 100644 (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;
index 5fca672..33dfcfe 100644 (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) {
index 96ae345..ef241a7 100644 (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];
 
index edd6f2e..cd0de2a 100644 (file)
@@ -141,6 +141,24 @@ gst_msdkenc_mbbrc_get_type (void)
 }
 
 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)
 {
   static GType type = 0;
index 56027a9..967ed5a 100644 (file)
@@ -64,6 +64,9 @@ GType
 gst_msdkenc_mbbrc_get_type (void);
 
 GType
+gst_msdkenc_lowdelay_brc_get_type (void);
+
+GType
 gst_msdkenc_adaptive_i_get_type (void);
 
 GType