msdk: encode: Add more rate control options
authorSreerenj Balachandran <sreerenj.balachandran@intel.com>
Wed, 14 Feb 2018 17:01:38 +0000 (17:01 +0000)
committerSreerenj Balachandran <sreerenj.balachandran@intel.com>
Tue, 20 Feb 2018 21:39:28 +0000 (12:39 -0900)
MediaSDK has support for a number of rate control algorithms.
Adding all possible options to the property rate-control.

Fixme1: In case of failure, currently we don't have a proper method
to show which rate-control has been failed. It could be better
to add some extensive validation on EncQuery output in case of error.
Unfortunately, not all ratecontrol methods are supported by every codecs
and we don't have the dynamic detection of supported ratecontrol methods yet.

https://bugzilla.gnome.org/show_bug.cgi?id=791637

sys/msdk/gstmsdkenc.c
sys/msdk/gstmsdkenc.h

index 2219a50..67a1ac5 100644 (file)
@@ -95,6 +95,11 @@ static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink",
 #define PROP_I_FRAMES_DEFAULT            0
 #define PROP_B_FRAMES_DEFAULT            0
 #define PROP_NUM_SLICES_DEFAULT          0
+#define PROP_AVBR_ACCURACY_DEFAULT       0
+#define PROP_AVBR_CONVERGENCE_DEFAULT    0
+#define PROP_RC_LOOKAHEAD_DEPTH_DEFAULT  10
+#define PROP_MAX_VBV_BITRATE_DEFAULT     0
+#define PROP_MAX_FRAME_SIZE_DEFAULT      0
 
 #define GST_MSDKENC_RATE_CONTROL_TYPE (gst_msdkenc_rate_control_get_type())
 static GType
@@ -107,6 +112,17 @@ gst_msdkenc_rate_control_get_type (void)
     {MFX_RATECONTROL_VBR, "Variable Bitrate", "vbr"},
     {MFX_RATECONTROL_CQP, "Constant Quantizer", "cqp"},
     {MFX_RATECONTROL_AVBR, "Average Bitrate", "avbr"},
+    {MFX_RATECONTROL_LA, "VBR with look ahead (Non HRD compliant)", "la_vbr"},
+    {MFX_RATECONTROL_ICQ, "Intelligent CQP", "icq"},
+    {MFX_RATECONTROL_VCM, "Video Conferencing Mode (Non HRD compliant)", "vcm"},
+    {MFX_RATECONTROL_LA_ICQ, "Intelligent CQP with LA (Non HRD compliant)",
+        "la_icq"},
+#if 0
+    /* intended for one to N transcode scenario */
+    {MFX_RATECONTROL_LA_EXT, "Extended LA", "la_ext"},
+#endif
+    {MFX_RATECONTROL_LA_HRD, "HRD compliant LA", "la_hrd"},
+    {MFX_RATECONTROL_QVBR, "VBR with CQP", "qvbr"},
     {0, NULL, NULL}
   };
 
@@ -149,6 +165,66 @@ gst_msdkenc_set_context (GstElement * element, GstContext * context)
   GST_ELEMENT_CLASS (parent_class)->set_context (element, context);
 }
 
+static void
+ensure_bitrate_control (GstMsdkEnc * thiz)
+{
+  mfxInfoMFX *mfx = &thiz->param.mfx;
+  mfxExtCodingOption2 *option2 = &thiz->option2;
+  mfxExtCodingOption3 *option3 = &thiz->option3;
+
+  mfx->RateControlMethod = thiz->rate_control;
+  /* No effect in CQP varient algorithms */
+  mfx->TargetKbps = thiz->bitrate;
+  mfx->MaxKbps = thiz->max_vbv_bitrate;
+
+  switch (mfx->RateControlMethod) {
+    case MFX_RATECONTROL_CQP:
+      mfx->QPI = thiz->qpi;
+      mfx->QPP = thiz->qpp;
+      mfx->QPB = thiz->qpb;
+      break;
+
+    case MFX_RATECONTROL_LA_ICQ:
+      option2->LookAheadDepth = thiz->lookahead_depth;
+      thiz->enable_extopt2 = TRUE;
+    case MFX_RATECONTROL_ICQ:
+      mfx->ICQQuality = CLAMP (thiz->qpi, 1, 51);
+      break;
+
+    case MFX_RATECONTROL_LA:   /* VBR with LA. Only supported in H264?? */
+    case MFX_RATECONTROL_LA_HRD:       /* VBR with LA, HRD compliant */
+      option2->LookAheadDepth = thiz->lookahead_depth;
+      thiz->enable_extopt2 = TRUE;
+      break;
+
+    case MFX_RATECONTROL_QVBR:
+      option3->QVBRQuality = CLAMP (thiz->qpi, 1, 51);
+      thiz->enable_extopt3 = TRUE;
+      break;
+
+    case MFX_RATECONTROL_AVBR:
+      mfx->Accuracy = thiz->accuracy;
+      mfx->Convergence = thiz->convergence;
+
+    case MFX_RATECONTROL_VBR:
+      option2->MaxFrameSize = thiz->max_frame_size * 1000;
+      thiz->enable_extopt2 = TRUE;
+      break;
+
+    case MFX_RATECONTROL_VCM:
+      /*Non HRD compliant mode with no B-frame and interlaced support */
+      thiz->param.mfx.GopRefDist = 0;
+      break;
+
+    case MFX_RATECONTROL_CBR:
+      break;
+
+    default:
+      GST_ERROR ("Unsupported RateControl!");
+      break;
+  }
+}
+
 static gboolean
 gst_msdkenc_init_encoder (GstMsdkEnc * thiz)
 {
@@ -288,8 +364,6 @@ gst_msdkenc_init_encoder (GstMsdkEnc * thiz)
   else
     thiz->param.IOPattern = MFX_IOPATTERN_IN_SYSTEM_MEMORY;
 
-  thiz->param.mfx.RateControlMethod = thiz->rate_control;
-  thiz->param.mfx.TargetKbps = thiz->bitrate;
   thiz->param.mfx.TargetUsage = thiz->target_usage;
   thiz->param.mfx.GopPicSize = thiz->gop_size;
   thiz->param.mfx.GopRefDist = thiz->b_frames + 1;
@@ -298,12 +372,6 @@ gst_msdkenc_init_encoder (GstMsdkEnc * thiz)
   thiz->param.mfx.NumRefFrame = thiz->ref_frames;
   thiz->param.mfx.EncodedOrder = 0;     /* Take input frames in display order */
 
-  if (thiz->rate_control == MFX_RATECONTROL_CQP) {
-    thiz->param.mfx.QPI = thiz->qpi;
-    thiz->param.mfx.QPP = thiz->qpp;
-    thiz->param.mfx.QPB = thiz->qpb;
-  }
-
   thiz->param.mfx.FrameInfo.Width = GST_ROUND_UP_32 (info->width);
   thiz->param.mfx.FrameInfo.Height = GST_ROUND_UP_32 (info->height);
   thiz->param.mfx.FrameInfo.CropW = info->width;
@@ -316,12 +384,26 @@ gst_msdkenc_init_encoder (GstMsdkEnc * thiz)
   thiz->param.mfx.FrameInfo.FourCC = MFX_FOURCC_NV12;
   thiz->param.mfx.FrameInfo.ChromaFormat = MFX_CHROMAFORMAT_YUV420;
 
+  /* ensure bitrate control parameters */
+  ensure_bitrate_control (thiz);
+
   /* allow subclass configure further */
   if (klass->configure) {
     if (!klass->configure (thiz))
       goto failed;
   }
 
+  if (thiz->enable_extopt2) {
+    thiz->option2.Header.BufferId = MFX_EXTBUFF_CODING_OPTION2;
+    thiz->option2.Header.BufferSz = sizeof (thiz->option2);
+    gst_msdkenc_add_extra_param (thiz, (mfxExtBuffer *) & thiz->option2);
+  }
+  if (thiz->enable_extopt3) {
+    thiz->option3.Header.BufferId = MFX_EXTBUFF_CODING_OPTION3;
+    thiz->option3.Header.BufferSz = sizeof (thiz->option3);
+    gst_msdkenc_add_extra_param (thiz, (mfxExtBuffer *) & thiz->option3);
+  }
+
   if (thiz->num_extra_params) {
     thiz->param.NumExtParam = thiz->num_extra_params;
     thiz->param.ExtParam = thiz->extra_params;
@@ -1297,6 +1379,11 @@ gst_msdkenc_init (GstMsdkEnc * thiz)
   thiz->target_usage = PROP_TARGET_USAGE_DEFAULT;
   thiz->rate_control = PROP_RATE_CONTROL_DEFAULT;
   thiz->bitrate = PROP_BITRATE_DEFAULT;
+  thiz->max_frame_size = PROP_MAX_FRAME_SIZE_DEFAULT;
+  thiz->max_vbv_bitrate = PROP_MAX_VBV_BITRATE_DEFAULT;
+  thiz->accuracy = PROP_AVBR_ACCURACY_DEFAULT;
+  thiz->convergence = PROP_AVBR_ACCURACY_DEFAULT;
+  thiz->lookahead_depth = PROP_RC_LOOKAHEAD_DEPTH_DEFAULT;
   thiz->qpi = PROP_QPI_DEFAULT;
   thiz->qpp = PROP_QPP_DEFAULT;
   thiz->qpb = PROP_QPB_DEFAULT;
@@ -1305,6 +1392,11 @@ gst_msdkenc_init (GstMsdkEnc * thiz)
   thiz->i_frames = PROP_I_FRAMES_DEFAULT;
   thiz->b_frames = PROP_B_FRAMES_DEFAULT;
   thiz->num_slices = PROP_NUM_SLICES_DEFAULT;
+
+  thiz->enable_extopt2 = FALSE;
+  thiz->enable_extopt3 = FALSE;
+  memset (&thiz->option2, 0, sizeof (thiz->option2));
+  memset (&thiz->option2, 0, sizeof (thiz->option3));
 }
 
 /* gst_msdkenc_set_common_property:
@@ -1566,7 +1658,8 @@ gst_msdkenc_install_common_properties (GstMsdkEncClass * klass)
 
   obj_properties[GST_MSDKENC_PROP_QPI] =
       g_param_spec_uint ("qpi", "QPI",
-      "Constant quantizer for I frames (0 unlimited)",
+      "Constant quantizer for I frames (0 unlimited). Also used as "
+      "ICQQuality or QVBRQuality for different RateControl methods",
       0, 51, PROP_QPI_DEFAULT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
 
   obj_properties[GST_MSDKENC_PROP_QPP] =
index baccb7d..76df76a 100644 (file)
@@ -114,6 +114,12 @@ struct _GstMsdkEnc
   mfxExtBuffer *extra_params[MAX_EXTRA_PARAMS];
   guint num_extra_params;
 
+  /* Additional encoder coding options */
+  mfxExtCodingOption2 option2;
+  gboolean enable_extopt2;
+  mfxExtCodingOption3 option3;
+  gboolean enable_extopt3;
+
   GstBufferPool *msdk_pool;
   GstBufferPool *msdk_converted_pool;
   GstVideoInfo aligned_info;
@@ -127,6 +133,11 @@ struct _GstMsdkEnc
   guint target_usage;
   guint rate_control;
   guint bitrate;
+  guint max_frame_size;
+  guint max_vbv_bitrate;
+  guint accuracy;
+  guint convergence;
+  guint lookahead_depth;
   guint qpi;
   guint qpp;
   guint qpb;