Merge "Enable cfi for aac"
diff --git a/libAACenc/src/aacenc.cpp b/libAACenc/src/aacenc.cpp
index b6f733d..1af8a2e 100644
--- a/libAACenc/src/aacenc.cpp
+++ b/libAACenc/src/aacenc.cpp
@@ -1,7 +1,7 @@
 /* -----------------------------------------------------------------------------
 Software License for The Fraunhofer FDK AAC Codec Library for Android
 
-© Copyright  1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten
+© Copyright  1995 - 2020 Fraunhofer-Gesellschaft zur Förderung der angewandten
 Forschung e.V. All rights reserved.
 
  1.    INTRODUCTION
@@ -245,6 +245,46 @@
   return bitrate;
 }
 
+/*-----------------------------------------------------------------------------
+
+    functionname: FDKaacEnc_AdjustVBRBitrateMode
+    description:  Adjust bitrate mode to given bitrate parameter
+    input params: int vbrQuality (VBR0, VBR1, VBR2)
+                  bitrate
+                  channelMode
+    returns:      vbr bitrate mode
+
+ ------------------------------------------------------------------------------*/
+AACENC_BITRATE_MODE FDKaacEnc_AdjustVBRBitrateMode(
+    AACENC_BITRATE_MODE bitrateMode, INT bitrate, CHANNEL_MODE channelMode) {
+  AACENC_BITRATE_MODE newBitrateMode = bitrateMode;
+
+  if (bitrate != -1) {
+    const INT monoStereoMode =
+        (FDKaacEnc_GetMonoStereoMode(channelMode) == EL_MODE_STEREO) ? 1 : 0;
+    const INT nChannelsEff =
+        FDKaacEnc_GetChannelModeConfiguration(channelMode)->nChannelsEff;
+    newBitrateMode = AACENC_BR_MODE_INVALID;
+
+    for (int idx = (int)(sizeof(configTabVBR) / sizeof(*configTabVBR)) - 1;
+         idx >= 0; idx--) {
+      if (bitrate >=
+          configTabVBR[idx].chanBitrate[monoStereoMode] * nChannelsEff) {
+        if (configTabVBR[idx].chanBitrate[monoStereoMode] * nChannelsEff <
+            FDKaacEnc_GetVBRBitrate(bitrateMode, channelMode)) {
+          newBitrateMode = configTabVBR[idx].bitrateMode;
+        } else {
+          newBitrateMode = bitrateMode;
+        }
+        break;
+      }
+    }
+  }
+
+  return AACENC_BR_MODE_IS_VBR(newBitrateMode) ? newBitrateMode
+                                               : AACENC_BR_MODE_INVALID;
+}
+
 /**
  * \brief  Convert encoder bitreservoir value for transport library.
  *
@@ -397,7 +437,6 @@
   FIXP_DBL mbfac, bw_ratio;
   QC_INIT qcInit;
   INT averageBitsPerFrame = 0;
-  int bitresMin = 0; /* the bitreservoir is always big for AAC-LC */
   const CHANNEL_MODE prevChannelMode = hAacEnc->encoderMode;
 
   if (config == NULL) return AAC_ENC_INVALID_HANDLE;
@@ -553,7 +592,6 @@
     qcInit.minBits = fixMin(qcInit.minBits, averageBitsPerFrame & ~7);
   } else {
     INT bitreservoir = -1; /* default bitreservoir size*/
-    bitresMin = BITRES_MIN;
     if (isLowDelay(config->audioObjectType)) {
       INT brPerChannel = config->bitRate / config->nChannels;
       brPerChannel = fMin(BITRATE_MAX_LD, fMax(BITRATE_MIN_LD, brPerChannel));
@@ -567,7 +605,6 @@
       bitreservoir = fMultI(slope, (INT)(BITRES_MAX_LD - BITRES_MIN_LD)) +
                      BITRES_MIN_LD;     /* interpolate */
       bitreservoir = bitreservoir & ~7; /* align to bytes */
-      bitresMin = BITRES_MIN_LD;
     }
 
     int maxBitres;
@@ -604,7 +641,8 @@
   qcInit.nSubFrames = config->nSubFrames;
   qcInit.padding.paddingRest = config->sampleRate;
 
-  if (qcInit.maxBits - qcInit.averageBits >= bitresMin * config->nChannels) {
+  if (qcInit.maxBits - qcInit.averageBits >=
+      ((qcInit.isLowDelay) ? BITRES_MIN_LD : BITRES_MIN) * config->nChannels) {
     qcInit.bitResMode = AACENC_BR_MODE_FULL; /* full bitreservoir */
   } else if (qcInit.maxBits > qcInit.averageBits) {
     qcInit.bitResMode = AACENC_BR_MODE_REDUCED; /* reduced bitreservoir */
diff --git a/libAACenc/src/aacenc.h b/libAACenc/src/aacenc.h
index 0e0d8c1..b7e0ef2 100644
--- a/libAACenc/src/aacenc.h
+++ b/libAACenc/src/aacenc.h
@@ -1,7 +1,7 @@
 /* -----------------------------------------------------------------------------
 Software License for The Fraunhofer FDK AAC Codec Library for Android
 
-© Copyright  1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
+© Copyright  1995 - 2020 Fraunhofer-Gesellschaft zur Förderung der angewandten
 Forschung e.V. All rights reserved.
 
  1.    INTRODUCTION
@@ -335,6 +335,19 @@
 
 /*-----------------------------------------------------------------------------
 
+    functionname: FDKaacEnc_AdjustVBRBitrateMode
+    description:  Adjust bitrate mode to given bitrate parameter
+    input params: int vbrQuality (VBR0, VBR1, VBR2)
+                  bitrate
+                  channelMode
+    returns:      vbr bitrate mode
+
+ ------------------------------------------------------------------------------*/
+AACENC_BITRATE_MODE FDKaacEnc_AdjustVBRBitrateMode(
+    AACENC_BITRATE_MODE bitrateMode, INT bitrate, CHANNEL_MODE channelMode);
+
+/*-----------------------------------------------------------------------------
+
      functionname: FDKaacEnc_AacInitDefaultConfig
      description:  gives reasonable default configuration
      returns:      ---
diff --git a/libAACenc/src/aacenc_lib.cpp b/libAACenc/src/aacenc_lib.cpp
index c3977f3..0ae329b 100644
--- a/libAACenc/src/aacenc_lib.cpp
+++ b/libAACenc/src/aacenc_lib.cpp
@@ -1028,6 +1028,13 @@
     case AACENC_BR_MODE_VBR_3:
     case AACENC_BR_MODE_VBR_4:
     case AACENC_BR_MODE_VBR_5:
+      /* Adjust bitrate mode in case given peak bitrate is lower than expected
+       * VBR bitrate. */
+      if ((INT)config->userPeakBitrate != -1) {
+        hAacConfig->bitrateMode = FDKaacEnc_AdjustVBRBitrateMode(
+            hAacConfig->bitrateMode, config->userPeakBitrate,
+            hAacConfig->channelMode);
+      }
       /* Get bitrate in VBR configuration */
       /* In VBR mode; SBR-modul depends on bitrate, core encoder on bitrateMode.
        */
diff --git a/libAACenc/src/qc_main.cpp b/libAACenc/src/qc_main.cpp
index bcfaa23..9a42550 100644
--- a/libAACenc/src/qc_main.cpp
+++ b/libAACenc/src/qc_main.cpp
@@ -1,7 +1,7 @@
 /* -----------------------------------------------------------------------------
 Software License for The Fraunhofer FDK AAC Codec Library for Android
 
-© Copyright  1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten
+© Copyright  1995 - 2020 Fraunhofer-Gesellschaft zur Förderung der angewandten
 Forschung e.V. All rights reserved.
 
  1.    INTRODUCTION
@@ -373,13 +373,8 @@
   hQC->invQuant = init->invQuant;
   hQC->maxIterations = init->maxIterations;
 
-  if (isConstantBitrateMode(hQC->bitrateMode)) {
-    /* 0: full bitreservoir, 1: reduced bitreservoir, 2: disabled bitreservoir
-     */
-    hQC->bitResMode = init->bitResMode;
-  } else {
-    hQC->bitResMode = AACENC_BR_MODE_FULL; /* full bitreservoir */
-  }
+  /* 0: full bitreservoir, 1: reduced bitreservoir, 2: disabled bitreservoir */
+  hQC->bitResMode = init->bitResMode;
 
   hQC->padding.paddingRest = init->padding.paddingRest;
 
@@ -800,10 +795,15 @@
   INT avgTotalDynBits = 0; /* maximal allowed dynamic bits for all frames */
   INT totalAvailableBits = 0;
   INT nSubFrames = 1;
+  const INT isCBRAdjustment = (isConstantBitrateMode(hQC->bitrateMode) ||
+                               (hQC->bitResMode != AACENC_BR_MODE_FULL))
+                                  ? 1
+                                  : 0;
 
   /*-------------------------------------------- */
   /* redistribute total bitreservoir to elements */
-  ErrorStatus = FDKaacEnc_BitResRedistribution(hQC, cm, avgTotalBits);
+  ErrorStatus = FDKaacEnc_BitResRedistribution(
+      hQC, cm, (isCBRAdjustment == 0) ? hQC->maxBitsPerFrame : avgTotalBits);
   if (ErrorStatus != AAC_ENC_OK) {
     return ErrorStatus;
   }
@@ -831,33 +831,22 @@
 
   /*-------------------------------------------- */
   /*-------------------------------------------- */
-  if (isConstantBitrateMode(hQC->bitrateMode)) {
-    /* calc granted dynamic bits for sub frame and
-       distribute it to each element */
-    ErrorStatus = FDKaacEnc_prepareBitDistribution(
-        hQC, psyOut, qcOut, cm, qcElement, avgTotalBits, &totalAvailableBits,
-        &avgTotalDynBits);
+  /* calc granted dynamic bits for sub frame and
+     distribute it to each element */
+  ErrorStatus = FDKaacEnc_prepareBitDistribution(
+      hQC, psyOut, qcOut, cm, qcElement,
+      (isCBRAdjustment == 0) ? hQC->maxBitsPerFrame : avgTotalBits,
+      &totalAvailableBits, &avgTotalDynBits);
 
-    if (ErrorStatus != AAC_ENC_OK) {
-      return ErrorStatus;
-    }
-  } else {
-    qcOut[0]->grantedDynBits =
-        ((hQC->maxBitsPerFrame - (hQC->globHdrBits)) & ~7) -
-        (qcOut[0]->globalExtBits + qcOut[0]->staticBits +
-         qcOut[0]->elementExtBits);
-    qcOut[0]->maxDynBits = qcOut[0]->grantedDynBits;
-
-    totalAvailableBits = hQC->maxBitsPerFrame;
-    avgTotalDynBits = 0;
+  if (ErrorStatus != AAC_ENC_OK) {
+    return ErrorStatus;
   }
 
   /* for ( all sub frames ) ... */
   for (c = 0; c < nSubFrames; c++) {
     /* for CBR and VBR mode */
     FDKaacEnc_AdjustThresholds(hQC->hAdjThr, qcElement[c], qcOut[c],
-                               psyOut[c]->psyOutElement,
-                               isConstantBitrateMode(hQC->bitrateMode), cm);
+                               psyOut[c]->psyOutElement, isCBRAdjustment, cm);
 
   } /* -end- sub frame counter */