From 02357506cf4baad4b10a197249ff30349bae8f96 Mon Sep 17 00:00:00 2001
From: Sanchayan Maity <sanchayan@asymptotic.io>
Date: Wed, 27 Jan 2021 23:36:19 +0530
Subject: [PATCH 6/7] fdkaacenc: Add support for setting bitrate mode

---
 .../gst-plugins-bad/ext/fdkaac/gstfdkaacenc.c | 44 ++++++++++++++++++-
 .../gst-plugins-bad/ext/fdkaac/gstfdkaacenc.h | 11 +++++
 2 files changed, 54 insertions(+), 1 deletion(-)

Index: gst-plugins-bad1.0-contrib/ext/fdkaac/gstfdkaacenc.c
===================================================================
--- gst-plugins-bad1.0-contrib.orig/ext/fdkaac/gstfdkaacenc.c
+++ gst-plugins-bad1.0-contrib/ext/fdkaac/gstfdkaacenc.c
@@ -31,6 +31,7 @@
 
 /* TODO:
  * - Add support for other AOT / profiles
+ * - Expose more properties, e.g. vbr
  * - Signal encoder delay
  */
 
@@ -39,6 +40,7 @@ enum
   PROP_0,
   PROP_AFTERBURNER,
   PROP_BITRATE,
+  PROP_BITRATEMODE,
   PROP_HEADER_PERIOD,
   PROP_PEAK_BITRATE,
   PROP_RATE_CONTROL,
@@ -146,6 +148,28 @@ gst_fdk_aac_rate_control_get_type (void)
   return fdk_aac_rate_control_type;
 }
 
+#define GST_AAC_BITRATEMODE (gst_aac_bitratemode_get_type ())
+static GType
+gst_aac_bitratemode_get_type (void)
+{
+  static GType aac_bitrate_mode_type = 0;
+  static const GEnumValue bitrate_mode_types[] = {
+    {GST_AAC_BITRATEMODE_CONSTANT, "Constant bitrate", "constant"},
+    {GST_AAC_BITRATEMODE_VERY_LOW, "Variable bitrate", "very low"},
+    {GST_AAC_BITRATEMODE_LOW, "Variable bitrate", "low"},
+    {GST_AAC_BITRATEMODE_MEDIUM, "Variable bitrate", "medium"},
+    {GST_AAC_BITRATEMODE_HIGH, "Variable bitrate", "high"},
+    {GST_AAC_BITRATEMODE_VERY_HIGH, "Variable bitrate", "very high"},
+    {0, NULL, NULL}
+  };
+
+  if (!aac_bitrate_mode_type)
+    aac_bitrate_mode_type =
+        g_enum_register_static ("GstAacBitrateMode", bitrate_mode_types);
+
+  return aac_bitrate_mode_type;
+}
+
 static void
 gst_fdkaacenc_set_property (GObject * object, guint prop_id,
     const GValue * value, GParamSpec * pspec)
@@ -168,6 +192,9 @@ gst_fdkaacenc_set_property (GObject * ob
     case PROP_VBR_PRESET:
       self->vbr_preset = g_value_get_enum (value);
       break;
+    case PROP_BITRATEMODE:
+      self->bitrate_mode = g_value_get_enum (value);
+      break;
     case PROP_HEADER_PERIOD:
       self->header_period = g_value_get_uint (value);
       break;
@@ -200,6 +227,9 @@ gst_fdkaacenc_get_property (GObject * ob
     case PROP_VBR_PRESET:
       g_value_set_enum (value, self->vbr_preset);
       break;
+    case PROP_BITRATEMODE:
+      g_value_set_enum (value, self->bitrate_mode);
+      break;
     case PROP_HEADER_PERIOD:
       g_value_set_uint (value, self->header_period);
       break;
@@ -562,6 +592,13 @@ gst_fdkaacenc_set_format (GstAudioEncode
     GST_INFO_OBJECT (self, "Afterburner enabled");
   }
 
+  if ((err = aacEncoder_SetParam (self->enc, AACENC_BITRATEMODE,
+              self->bitrate_mode)) != AACENC_OK) {
+    GST_ERROR_OBJECT (self, "Unable to set bitrate mode %d: %d",
+        self->bitrate_mode, err);
+    return FALSE;
+  }
+
   if ((err = aacEncoder_SetParam (self->enc, AACENC_HEADER_PERIOD,
               self->header_period)) != AACENC_OK) {
     GST_ERROR_OBJECT (self, "Unable to set header period %d: %d",
@@ -806,6 +843,7 @@ static void
 gst_fdkaacenc_init (GstFdkAacEnc * self)
 {
   self->bitrate = DEFAULT_BITRATE;
+  self->bitrate_mode = GST_AAC_BITRATEMODE_CONSTANT;
   self->enc = NULL;
   self->is_drained = TRUE;
   self->afterburner = FALSE;
@@ -894,6 +932,12 @@ gst_fdkaacenc_class_init (GstFdkAacEncCl
           GST_FDK_AAC_VBR_PRESET, DEFAULT_VBR_PRESET,
           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
+  g_object_class_install_property (object_class, PROP_BITRATEMODE,
+      g_param_spec_enum ("bitrate-mode", "Bitrate Mode",
+          "AAC Bitrate configurations",
+          GST_AAC_BITRATEMODE, GST_AAC_BITRATEMODE_CONSTANT,
+          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
   g_object_class_install_property (object_class, PROP_HEADER_PERIOD,
       g_param_spec_uint ("header-period", "Frame count period",
           "Frame count period for sending in-band configuration buffers",
Index: gst-plugins-bad1.0-contrib/ext/fdkaac/gstfdkaacenc.h
===================================================================
--- gst-plugins-bad1.0-contrib.orig/ext/fdkaac/gstfdkaacenc.h
+++ gst-plugins-bad1.0-contrib/ext/fdkaac/gstfdkaacenc.h
@@ -73,6 +73,16 @@ typedef enum
   GST_FDK_AAC_RATE_CONTROL_VARIABLE_BITRATE,
 } GstFdkAacRateControl;
 
+typedef enum
+{
+  GST_AAC_BITRATEMODE_CONSTANT = 0,
+  GST_AAC_BITRATEMODE_VERY_LOW,
+  GST_AAC_BITRATEMODE_LOW,
+  GST_AAC_BITRATEMODE_MEDIUM,
+  GST_AAC_BITRATEMODE_HIGH,
+  GST_AAC_BITRATEMODE_VERY_HIGH
+} GstAacBitrateMode;
+
 struct _GstFdkAacEnc {
   GstAudioEncoder element;
 
@@ -84,6 +94,7 @@ struct _GstFdkAacEnc {
   const GstAudioChannelPosition *aac_positions;
   gboolean is_drained;
 
+  GstAacBitrateMode bitrate_mode;
   guint header_period;
 
   guint peak_bitrate;
