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(-)

diff --git a/ext/fdkaac/gstfdkaacenc.c b/ext/fdkaac/gstfdkaacenc.c
index 7c8372e3b5..de9c18612f 100644
--- a/ext/fdkaac/gstfdkaacenc.c
+++ b/ext/fdkaac/gstfdkaacenc.c
@@ -31,7 +31,6 @@
 
 /* TODO:
  * - Add support for other AOT / profiles
- * - Expose more properties, e.g. vbr
  * - Signal encoder delay
  */
 
@@ -40,6 +39,7 @@ enum
   PROP_0,
   PROP_AFTERBURNER,
   PROP_BITRATE,
+  PROP_BITRATEMODE,
   PROP_HEADER_PERIOD
 };
 
@@ -100,6 +100,28 @@ G_DEFINE_TYPE (GstFdkAacEnc, gst_fdkaacenc, GST_TYPE_AUDIO_ENCODER);
 GST_ELEMENT_REGISTER_DEFINE (fdkaacenc, "fdkaacenc", GST_RANK_PRIMARY,
     GST_TYPE_FDKAACENC);
 
+#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)
@@ -110,6 +132,9 @@ gst_fdkaacenc_set_property (GObject * object, guint prop_id,
     case PROP_BITRATE:
       self->bitrate = g_value_get_int (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;
@@ -133,6 +158,9 @@ gst_fdkaacenc_get_property (GObject * object, guint prop_id,
     case PROP_BITRATE:
       g_value_set_int (value, self->bitrate);
       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;
@@ -404,6 +432,13 @@ gst_fdkaacenc_set_format (GstAudioEncoder * enc, GstAudioInfo * info)
     return FALSE;
   }
 
+  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) {
@@ -643,6 +678,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;
   /*
@@ -680,6 +716,12 @@ gst_fdkaacenc_class_init (GstFdkAacEncClass * klass)
           0, G_MAXINT, DEFAULT_BITRATE,
           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",
diff --git a/ext/fdkaac/gstfdkaacenc.h b/ext/fdkaac/gstfdkaacenc.h
index 1da85b8891..6b24cf7bb4 100644
--- a/ext/fdkaac/gstfdkaacenc.h
+++ b/ext/fdkaac/gstfdkaacenc.h
@@ -41,6 +41,16 @@ G_BEGIN_DECLS
 typedef struct _GstFdkAacEnc GstFdkAacEnc;
 typedef struct _GstFdkAacEncClass GstFdkAacEncClass;
 
+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;
 
@@ -52,6 +62,7 @@ struct _GstFdkAacEnc {
   const GstAudioChannelPosition *aac_positions;
   gboolean is_drained;
 
+  GstAacBitrateMode bitrate_mode;
   guint header_period;
   gboolean afterburner;
 };
-- 
2.34.1

