AAC-Decoder: SBR delay for gapless

Revise decoder output delay determination. The output delay consisted of
  concealment and limiter delay. SBR delay was not covered but must be
  considered for gapless playback delay compensation.

Bug 9428126

Change-Id: I67483712c284de9b5378694f9db7acbed2547dd7
diff --git a/libAACdec/src/aacdecoder_lib.cpp b/libAACdec/src/aacdecoder_lib.cpp
index 8e3027a..82f85ab 100644
--- a/libAACdec/src/aacdecoder_lib.cpp
+++ b/libAACdec/src/aacdecoder_lib.cpp
@@ -110,7 +110,7 @@
 /* Decoder library info */
 #define AACDECODER_LIB_VL0 2
 #define AACDECODER_LIB_VL1 5
-#define AACDECODER_LIB_VL2 9
+#define AACDECODER_LIB_VL2 10
 #define AACDECODER_LIB_TITLE "AAC Decoder Lib"
 #define AACDECODER_LIB_BUILD_DATE __DATE__
 #define AACDECODER_LIB_BUILD_TIME __TIME__
@@ -954,19 +954,22 @@
 
 
      if (sbrError == SBRDEC_OK) {
+       #define UPS_SCALE  2  /* Maximum upsampling factor is 4 (CELP+SBR) */
+       FIXP_DBL  upsampleFactor = FL2FXCONST_DBL(1.0f/(1<<UPS_SCALE));
 
        /* Update data in streaminfo structure. Assume that the SBR upsampling factor is either 1 or 2 */
        self->flags |= AC_SBR_PRESENT;
        if (self->streamInfo.aacSampleRate != self->streamInfo.sampleRate) {
          if (self->streamInfo.frameSize == 768) {
-           self->streamInfo.frameSize =  (self->streamInfo.aacSamplesPerFrame * 8) / 3;
+           upsampleFactor = FL2FXCONST_DBL(8.0f/(3<<UPS_SCALE));
          } else {
-           self->streamInfo.frameSize =  self->streamInfo.aacSamplesPerFrame << 1;
+           upsampleFactor = FL2FXCONST_DBL(2.0f/(1<<UPS_SCALE));
          }
        }
-       /* Correct the additional concealment delay figures */
-       self->streamInfo.outputDelay -= self->sbrParams.bsDelay * self->streamInfo.aacSamplesPerFrame;
-       self->streamInfo.outputDelay += self->sbrParams.bsDelay * self->streamInfo.frameSize;
+       /* Apply upsampling factor to both the core frame length and the core delay */
+       self->streamInfo.frameSize    =       (INT)fMult((FIXP_DBL)self->streamInfo.aacSamplesPerFrame<<UPS_SCALE, upsampleFactor);
+       self->streamInfo.outputDelay  = (UINT)(INT)fMult((FIXP_DBL)self->streamInfo.outputDelay<<UPS_SCALE, upsampleFactor);
+       self->streamInfo.outputDelay += sbrDecoder_GetDelay( self->hSbrDecoder );
 
        if (self->psPossible) {
          self->flags |= AC_PS_PRESENT;
diff --git a/libSBRdec/include/sbrdecoder.h b/libSBRdec/include/sbrdecoder.h
index 36a4739..174fb5c 100644
--- a/libSBRdec/include/sbrdecoder.h
+++ b/libSBRdec/include/sbrdecoder.h
@@ -331,6 +331,13 @@
  */
 INT sbrDecoder_GetLibInfo( LIB_INFO *info );    
 
+/**
+ * \brief       Determine the modules output signal delay in samples.
+ * \param self  SBR decoder handle.
+ * \return      The number of samples signal delay added by the module.
+ */
+UINT sbrDecoder_GetDelay( const HANDLE_SBRDECODER self );
+
 
 #ifdef __cplusplus
 }
diff --git a/libSBRdec/src/env_extr.h b/libSBRdec/src/env_extr.h
index ddbfa18..ab6b704 100644
--- a/libSBRdec/src/env_extr.h
+++ b/libSBRdec/src/env_extr.h
@@ -179,6 +179,7 @@
 #define SBRDEC_LOW_POWER      16  /* Flag indicating that Low Power QMF mode shall be used. */
 #define SBRDEC_PS_DECODED     32  /* Flag indicating that PS was decoded and rendered. */
 #define SBRDEC_LD_MPS_QMF    512  /* Flag indicating that the LD-MPS QMF shall be used. */
+#define SBRDEC_DOWNSAMPLE   8192  /* Flag indicating that the downsampling mode is used. */
 #define SBRDEC_FLUSH       16384  /* Flag is used to flush all elements in use. */
 #define SBRDEC_FORCE_RESET 32768  /* Flag is used to force a reset of all elements in use. */
 
diff --git a/libSBRdec/src/sbrdecoder.cpp b/libSBRdec/src/sbrdecoder.cpp
index bed23c7..16b0bbc 100644
--- a/libSBRdec/src/sbrdecoder.cpp
+++ b/libSBRdec/src/sbrdecoder.cpp
@@ -137,7 +137,7 @@
 /* Decoder library info */
 #define SBRDECODER_LIB_VL0 2
 #define SBRDECODER_LIB_VL1 2
-#define SBRDECODER_LIB_VL2 5
+#define SBRDECODER_LIB_VL2 6
 #define SBRDECODER_LIB_TITLE "SBR Decoder"
 #define SBRDECODER_LIB_BUILD_DATE __DATE__
 #define SBRDECODER_LIB_BUILD_TIME __TIME__
@@ -251,8 +251,10 @@
 
   if ( sampleRateIn == sampleRateOut ) {
     synDownsampleFac = 2;
+    self->flags |=  SBRDEC_DOWNSAMPLE;
   } else {
     synDownsampleFac = 1;
+    self->flags &= ~SBRDEC_DOWNSAMPLE;
   }
 
   self->synDownsampleFac = synDownsampleFac;
@@ -1582,3 +1584,34 @@
   return 0;
 }
 
+
+UINT sbrDecoder_GetDelay( const HANDLE_SBRDECODER self )
+{
+  UINT outputDelay = 0;
+
+  if ( self != NULL) {
+    UINT flags = self->flags;
+
+    /* See chapter 1.6.7.2 of ISO/IEC 14496-3 for the GA-SBR figures below. */
+
+    /* Are we initialized? */
+    if ( (self->numSbrChannels > 0)
+      && (self->numSbrElements > 0) )
+    {
+      /* Add QMF synthesis delay */
+      if ( (flags & SBRDEC_ELD_GRID)
+        && IS_LOWDELAY(self->coreCodec) ) {
+        /* Low delay SBR: */
+        {
+          outputDelay += (flags & SBRDEC_DOWNSAMPLE) ? 32 : 64;   /* QMF synthesis */
+        }
+      }
+      else if (!IS_USAC(self->coreCodec)) {
+        /* By the method of elimination this is the GA (AAC-LC, HE-AAC, ...) branch: */
+        outputDelay += (flags & SBRDEC_DOWNSAMPLE) ? 481 : 962;
+      }
+    }
+  }
+
+  return (outputDelay);
+}
diff --git a/libSYS/include/FDK_audio.h b/libSYS/include/FDK_audio.h
index 97770a7..0660f4c 100644
--- a/libSYS/include/FDK_audio.h
+++ b/libSYS/include/FDK_audio.h
@@ -232,6 +232,14 @@
 
 } AUDIO_OBJECT_TYPE;
 
+#define IS_USAC(aot) \
+  ((aot) == AOT_USAC \
+|| (aot) == AOT_RSVD50)
+
+#define IS_LOWDELAY(aot) \
+  ((aot) == AOT_ER_AAC_LD \
+|| (aot) == AOT_ER_AAC_ELD)
+
 /** Channel Mode ( 1-7 equals MPEG channel configurations, others are arbitrary). */
 typedef enum {
   MODE_INVALID                  = -1,
diff --git a/libSYS/src/genericStds.cpp b/libSYS/src/genericStds.cpp
index e67db38..3381e37 100644
--- a/libSYS/src/genericStds.cpp
+++ b/libSYS/src/genericStds.cpp
@@ -99,7 +99,7 @@
 /* library info */
 #define SYS_LIB_VL0 1
 #define SYS_LIB_VL1 3
-#define SYS_LIB_VL2 5
+#define SYS_LIB_VL2 6
 #define SYS_LIB_TITLE "System Integration Library"
 #define SYS_LIB_BUILD_DATE __DATE__
 #define SYS_LIB_BUILD_TIME __TIME__