aboutsummaryrefslogtreecommitdiffstats
path: root/libAACdec/src
diff options
context:
space:
mode:
authorJean-Michel Trivi <jmtrivi@google.com>2016-04-08 12:05:12 -0700
committerJean-Michel Trivi <jmtrivi@google.com>2016-04-08 19:10:30 +0000
commit203e3f28fbebec7011342017fafc2a0bda0ce530 (patch)
tree359ed01256a717b0161bfba21783634f1250471a /libAACdec/src
parent46ba3676b854acbc69a4c7845f578d4c2886377b (diff)
downloadfdk-aac-203e3f28fbebec7011342017fafc2a0bda0ce530.tar.gz
fdk-aac-203e3f28fbebec7011342017fafc2a0bda0ce530.tar.bz2
fdk-aac-203e3f28fbebec7011342017fafc2a0bda0ce530.zip
AAC/SBR decoder improvements and bugfixes
* AAC-Decoder - Add support for AOT 20 (ER-AAC scalable) (base layer only) - Add support for AAC as used in Digital Radio Mondiale (DRM30/DRM+) Modified file(s): libAACdec/src/aacdecoder.cpp libAACdec/src/aacdecoder_lib.cpp libFDK/src/FDK_core.cpp libFDK/src/FDK_tools_rom.cpp libMpegTPDec/src/tpdec_asc.cpp libMpegTPDec/src/tpdec_lib.cpp libMpegTPDec/src/version libSBRdec/include/sbrdecoder.h libSBRdec/src/env_extr.h libSBRdec/src/sbrdecoder.cpp Added file(s): libMpegTPDec/src/tpdec_drm.cpp libMpegTPDec/src/tpdec_drm.h - Fix sanity check in HCR module that was performed at the wrong point in time. Modified file(s): libAACdec/src/aacdecoder_lib.cpp libAACdec/src/block.cpp - Extend core sampling rate support up to 96 kHz. Modified file(s): libAACdec/src/aac_rom.cpp libAACdec/src/aacdecoder.cpp libAACdec/src/aacdecoder_lib.cpp - Return correct audio output channel description according number of output channels. Modified file(s): libAACdec/src/aacdecoder_lib.cpp - Indroduce decoder intern output buffer. This change allows to use framework output buffer with the actual size of the deocder output channels. Modified file(s): libAACdec/include/aacdecoder_lib.h libAACdec/src/aacdecoder.h libAACdec/src/aacdecoder_lib.cpp * SBR-Decoder - Increase robustness for erroneous input data. - Improve error concealment performance. - Fix handling of lowest sub-band for LD-SBR Modified file(s): libAACdec/src/aacdecoder.cpp libAACdec/src/aacdecoder_lib.cpp libSBRdec/src/env_calc.cpp libSBRdec/src/env_dec.cpp libSBRdec/src/env_extr.cpp libSBRdec/src/env_extr.h libSBRdec/src/sbr_dec.cpp libSBRdec/src/sbr_rom.cpp libSBRdec/src/sbr_rom.h libSBRdec/src/sbrdecoder.cpp - Add QMF delay compensation for ELD v2 streams decoded with the complex low delay filter-bank. Modified file(s): libSBRdec/src/sbr_dec.cpp libSBRdec/src/sbr_dec.h libSBRdec/src/sbrdecoder.cpp - Introduce a different handling of frames to be flushed dependent on whether there are delayed frames available or not. Modified file(s): libSBRdec/src/sbr_ram.h libSBRdec/src/sbrdecoder.cpp - Calculate the correct number of samples for dual-mono copy in case of no available PS data. Modified file(s): libSBRdec/src/sbrdecoder.cpp * SYS-Library - Change include order of genericStds.h to prevent conflict with definitions which are also used in math.h. Modified file(s): libSYS/src/genericStds.cpp Change-Id: I3ecffbad85f39b056213107955cfadbeb3f4b6e1
Diffstat (limited to 'libAACdec/src')
-rw-r--r--libAACdec/src/aac_rom.cpp85
-rw-r--r--libAACdec/src/aacdecoder.cpp37
-rw-r--r--libAACdec/src/aacdecoder.h4
-rw-r--r--libAACdec/src/aacdecoder_lib.cpp43
-rw-r--r--libAACdec/src/block.cpp6
5 files changed, 143 insertions, 32 deletions
diff --git a/libAACdec/src/aac_rom.cpp b/libAACdec/src/aac_rom.cpp
index 607cb3b..f3c9b5a 100644
--- a/libAACdec/src/aac_rom.cpp
+++ b/libAACdec/src/aac_rom.cpp
@@ -2,7 +2,7 @@
/* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
-© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
+© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved.
1. INTRODUCTION
@@ -167,6 +167,36 @@ const SCHAR ExponentTable [4][14] =
} ;
+/* 41 scfbands */
+static const SHORT sfb_96_1024[42] =
+{
+ 0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44,
+ 48, 52, 56, 64, 72, 80, 88, 96, 108, 120, 132, 144,
+ 156, 172, 188, 212, 240, 276, 320, 384, 448, 512, 576, 640,
+ 704, 768, 832, 896, 960, 1024
+};
+/* 12 scfbands */
+static const SHORT sfb_96_128[13] =
+{
+ 0, 4, 8, 12, 16, 20, 24, 32, 40, 48, 64, 92,
+ 128
+};
+
+/* 47 scfbands*/
+static const SHORT sfb_64_1024[48] =
+{
+ 0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52,
+ 56, 64, 72, 80, 88, 100, 112, 124, 140, 156, 172, 192, 216, 240,
+ 268, 304, 344, 384, 424, 464, 504, 544, 584, 624, 664, 704, 744, 784,
+ 824, 864, 904, 944, 984,1024
+};
+
+/* 12 scfbands */
+static const SHORT sfb_64_128[13] =
+{
+ 0, 4, 8, 12, 16, 20, 24,
+ 32, 40, 48, 64, 92, 128
+};
/* 49 scfbands */
static const SHORT sfb_48_1024[50] = {
@@ -239,6 +269,35 @@ static const SHORT sfb_8_128[16] =
};
+static const SHORT sfb_96_960[42] =
+{
+ 0, 4, 8, 12, 16, 20, 24, 28, 32, 36,
+ 40, 44, 48, 52, 56, 64, 72, 80, 88, 96,
+ 108, 120, 132, 144, 156, 172, 188, 212, 240, 276,
+ 320, 384, 448, 512, 576, 640, 704, 768, 832, 896,
+ 960
+}; /* 40 scfbands */
+
+static const SHORT sfb_96_120[13] =
+{
+ 0, 4, 8, 12, 16, 20, 24, 32, 40, 48,
+ 64, 92, 120
+}; /* 12 scfbands */
+
+static const SHORT sfb_64_960[47] =
+{
+ 0, 4, 8, 12, 16, 20, 24, 28, 32, 36,
+ 40, 44, 48, 52, 56, 64, 72, 80, 88, 100,
+ 112, 124, 140, 156, 172, 192, 216, 240, 268, 304,
+ 344, 384, 424, 464, 504, 544, 584, 624, 664, 704,
+ 744, 784, 824, 864, 904, 944, 960
+}; /* 46 scfbands */
+
+static const SHORT sfb_64_120[13] =
+{
+ 0, 4, 8, 12, 16, 20, 24, 32, 40, 48,
+ 64, 92, 120
+}; /* 12 scfbands */
static const SHORT sfb_48_960[50] =
{
@@ -358,9 +417,9 @@ static const SHORT sfb_24_480[31] =
const SFB_INFO sfbOffsetTables[5][16] =
{
{
- { NULL, NULL, 0, 0 },
- { NULL, NULL, 0, 0 },
- { NULL, NULL, 0, 0 },
+ { sfb_96_1024, sfb_96_128, 41, 12 },
+ { sfb_96_1024, sfb_96_128, 41, 12 },
+ { sfb_64_1024, sfb_64_128, 47, 12 },
{ sfb_48_1024, sfb_48_128, 49, 14 },
{ sfb_48_1024, sfb_48_128, 49, 14 },
{ sfb_32_1024, sfb_48_128, 51, 14 },
@@ -372,9 +431,9 @@ const SFB_INFO sfbOffsetTables[5][16] =
{ sfb_8_1024, sfb_8_128, 40, 15 },
{ sfb_8_1024, sfb_8_128, 40, 15 },
}, {
- { NULL, NULL, 0, 0 },
- { NULL, NULL, 0, 0 },
- { NULL, NULL, 0, 0 },
+ { sfb_96_960, sfb_96_120, 40, 12 },
+ { sfb_96_960, sfb_96_120, 40, 12 },
+ { sfb_64_960, sfb_64_120, 46, 12 },
{ sfb_48_960, sfb_48_120, 49, 14 },
{ sfb_48_960, sfb_48_120, 49, 14 },
{ sfb_32_960, sfb_48_120, 49, 14 },
@@ -388,9 +447,9 @@ const SFB_INFO sfbOffsetTables[5][16] =
}, {
{ NULL, NULL, 0, 0 },
}, {
- { NULL, NULL, 0, 0 },
- { NULL, NULL, 0, 0 },
- { NULL, NULL, 0, 0 },
+ { sfb_48_512, NULL, 36, 0 },
+ { sfb_48_512, NULL, 36, 0 },
+ { sfb_48_512, NULL, 36, 0 },
{ sfb_48_512, NULL, 36, 0 },
{ sfb_48_512, NULL, 36, 0},
{ sfb_32_512, NULL, 37, 0 },
@@ -402,9 +461,9 @@ const SFB_INFO sfbOffsetTables[5][16] =
{ sfb_24_512, NULL, 31, 0 },
{ sfb_24_512, NULL, 31, 0 },
}, {
- { NULL, NULL, 0, 0 },
- { NULL, NULL, 0, 0 },
- { NULL, NULL, 0, 0 },
+ { sfb_48_480, NULL, 35, 0 },
+ { sfb_48_480, NULL, 35, 0 },
+ { sfb_48_480, NULL, 35, 0 },
{ sfb_48_480, NULL, 35, 0 },
{ sfb_48_480, NULL, 35, 0 },
{ sfb_32_480, NULL, 37, 0 },
diff --git a/libAACdec/src/aacdecoder.cpp b/libAACdec/src/aacdecoder.cpp
index 8270f69..579e470 100644
--- a/libAACdec/src/aacdecoder.cpp
+++ b/libAACdec/src/aacdecoder.cpp
@@ -157,6 +157,7 @@ amm-info@iis.fraunhofer.de
#include "conceal.h"
+ #include "FDK_crc.h"
void CAacDecoder_SyncQmfMode(HANDLE_AACDECODER self)
@@ -537,8 +538,9 @@ AAC_DECODER_ERROR CAacDecoder_ExtPayloadParse (HANDLE_AACDECODER self,
previous_element,
elIndex,
self->flags & AC_INDEP );
- /* Enable SBR for implicit SBR signalling. */
- if (sbrError == SBRDEC_OK) {
+ /* Enable SBR for implicit SBR signalling but only if no severe error happend. */
+ if ( (sbrError == SBRDEC_OK)
+ || (sbrError == SBRDEC_PARSE_ERROR) ) {
self->sbrEnabled = 1;
}
} else {
@@ -553,7 +555,7 @@ AAC_DECODER_ERROR CAacDecoder_ExtPayloadParse (HANDLE_AACDECODER self,
FDKpushBiDirectional(hBs, *count);
*count = 0;
} else {
- /* If this is not a fill element with a known length, we are screwed an no further parsing makes sense. */
+ /* If this is not a fill element with a known length, we are screwed and further parsing makes no sense. */
if (sbrError != SBRDEC_OK) {
self->frameOK = 0;
}
@@ -832,12 +834,18 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_Init(HANDLE_AACDECODER self, const CS
switch (asc->m_aot) {
case AOT_AAC_LC:
self->streamInfo.profile = 1;
- break;
+
+ case AOT_ER_AAC_SCAL:
+ if (asc->m_sc.m_gaSpecificConfig.m_layer > 0) {
+ /* aac_scalable_extension_element() currently not supported. */
+ return AAC_DEC_UNSUPPORTED_FORMAT;
+ }
case AOT_SBR:
case AOT_PS:
case AOT_ER_AAC_LD:
case AOT_ER_AAC_ELD:
+ case AOT_DRM_AAC:
break;
default:
@@ -957,11 +965,20 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_Init(HANDLE_AACDECODER self, const CS
if (asc->m_aot == AOT_ER_AAC_ELD) {
self->flags |= AC_ELD;
+ self->flags |= (asc->m_sbrPresentFlag) ? AC_SBR_PRESENT : 0; /* Need to set the SBR flag for backward-compatibility
+ reasons. Even if SBR is not supported. */
self->flags |= (asc->m_sc.m_eldSpecificConfig.m_sbrCrcFlag) ? AC_SBRCRC : 0;
self->flags |= (asc->m_sc.m_eldSpecificConfig.m_useLdQmfTimeAlign) ? AC_LD_MPS : 0;
}
self->flags |= (asc->m_aot == AOT_ER_AAC_LD) ? AC_LD : 0;
self->flags |= (asc->m_epConfig >= 0) ? AC_ER : 0;
+ if ( asc->m_aot == AOT_DRM_AAC ) {
+ self->flags |= AC_DRM|AC_SBRCRC|AC_SCALABLE;
+ }
+ if ( (asc->m_aot == AOT_AAC_SCAL)
+ || (asc->m_aot == AOT_ER_AAC_SCAL) ) {
+ self->flags |= AC_SCALABLE;
+ }
if (asc->m_sbrPresentFlag) {
@@ -1147,6 +1164,9 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame(
/* Check sampling frequency */
switch ( self->streamInfo.aacSampleRate ) {
+ case 96000:
+ case 88200:
+ case 64000:
case 16000:
case 12000:
case 11025:
@@ -1475,7 +1495,7 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame(
/* get the remaining bits of this frame */
bitCnt = transportDec_GetAuBitsRemaining(self->hInput, 0);
- if ( (bitCnt > 0) && (self->flags & AC_SBR_PRESENT) && (self->flags & (AC_USAC|AC_RSVD50|AC_ELD)) )
+ if ( (bitCnt > 0) && (self->flags & AC_SBR_PRESENT) && (self->flags & (AC_USAC|AC_RSVD50|AC_ELD|AC_DRM)) )
{
SBR_ERROR err = SBRDEC_OK;
int elIdx, numChElements = el_cnt[ID_SCE] + el_cnt[ID_CPE];
@@ -1513,6 +1533,13 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame(
}
+ if (self->flags & AC_DRM)
+ {
+ if ((bitCnt = (INT)FDKgetValidBits(bs)) != 0) {
+ FDKpushBiDirectional(bs, bitCnt);
+ }
+ }
+
if ( ! (self->flags & (AC_USAC|AC_RSVD50|AC_DRM)) )
{
while ( bitCnt > 7 ) {
diff --git a/libAACdec/src/aacdecoder.h b/libAACdec/src/aacdecoder.h
index 3541773..25bc35d 100644
--- a/libAACdec/src/aacdecoder.h
+++ b/libAACdec/src/aacdecoder.h
@@ -2,7 +2,7 @@
/* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
-© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
+© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved.
1. INTRODUCTION
@@ -226,6 +226,8 @@ struct AAC_DECODER_INSTANCE {
FIXP_DBL extGain[1]; /*!< Gain that must be applied to the output signal. */
UINT extGainDelay; /*!< Delay that must be accounted for extGain. */
+ INT_PCM pcmOutputBuffer[(8)*(2048)];
+
};
diff --git a/libAACdec/src/aacdecoder_lib.cpp b/libAACdec/src/aacdecoder_lib.cpp
index b501eb9..8863da5 100644
--- a/libAACdec/src/aacdecoder_lib.cpp
+++ b/libAACdec/src/aacdecoder_lib.cpp
@@ -110,7 +110,7 @@ amm-info@iis.fraunhofer.de
/* Decoder library info */
#define AACDECODER_LIB_VL0 2
#define AACDECODER_LIB_VL1 5
-#define AACDECODER_LIB_VL2 11
+#define AACDECODER_LIB_VL2 17
#define AACDECODER_LIB_TITLE "AAC Decoder Lib"
#ifdef __ANDROID__
#define AACDECODER_LIB_BUILD_DATE ""
@@ -181,8 +181,9 @@ LINKSPEC_CPP AAC_DECODER_ERROR aacDecoder_ConfigRaw (
break;
}
/* if baselayer is OK we continue decoding */
- if(layer >= 1){
+ if(layer >= 1){
self->nrOfLayers = layer;
+ err = AAC_DEC_OK;
}
break;
}
@@ -785,8 +786,8 @@ static INT aacDecoder_EstimateNumberOfLostFrames(HANDLE_AACDECODER self)
LINKSPEC_CPP AAC_DECODER_ERROR aacDecoder_DecodeFrame(
HANDLE_AACDECODER self,
- INT_PCM *pTimeData,
- const INT timeDataSize,
+ INT_PCM *pTimeData_extern,
+ const INT timeDataSize_extern,
const UINT flags)
{
AAC_DECODER_ERROR ErrorStatus;
@@ -796,12 +797,17 @@ LINKSPEC_CPP AAC_DECODER_ERROR aacDecoder_DecodeFrame(
HANDLE_FDK_BITSTREAM hBs;
int fTpInterruption = 0; /* Transport originated interruption detection. */
int fTpConceal = 0; /* Transport originated concealment. */
+ INT_PCM *pTimeData = NULL;
+ INT timeDataSize = 0;
if (self == NULL) {
return AAC_DEC_INVALID_HANDLE;
}
+ pTimeData = self->pcmOutputBuffer;
+ timeDataSize = sizeof(self->pcmOutputBuffer)/sizeof(*self->pcmOutputBuffer);
+
if (flags & AACDEC_INTR) {
self->streamInfo.numLostAccessUnits = 0;
}
@@ -918,7 +924,8 @@ LINKSPEC_CPP AAC_DECODER_ERROR aacDecoder_DecodeFrame(
if (self->sbrEnabled)
{
SBR_ERROR sbrError = SBRDEC_OK;
- int chOutMapIdx = ((self->chMapIndex==0) && (self->streamInfo.numChannels<7)) ? self->streamInfo.numChannels : self->chMapIndex;
+ int chIdx, numCoreChannel = self->streamInfo.numChannels;
+ int chOutMapIdx = ((self->chMapIndex==0) && (numCoreChannel<7)) ? numCoreChannel : self->chMapIndex;
/* set params */
sbrDecoder_SetParam ( self->hSbrDecoder,
@@ -978,10 +985,10 @@ LINKSPEC_CPP AAC_DECODER_ERROR aacDecoder_DecodeFrame(
if (self->psPossible) {
self->flags |= AC_PS_PRESENT;
- self->channelType[0] = ACT_FRONT;
- self->channelType[1] = ACT_FRONT;
- self->channelIndices[0] = 0;
- self->channelIndices[1] = 1;
+ }
+ for (chIdx = numCoreChannel; chIdx < self->streamInfo.numChannels; chIdx+=1) {
+ self->channelType[chIdx] = ACT_FRONT;
+ self->channelIndices[chIdx] = chIdx;
}
}
}
@@ -1006,7 +1013,8 @@ LINKSPEC_CPP AAC_DECODER_ERROR aacDecoder_DecodeFrame(
self->channelOutputMapping,
(self->limiterEnableCurr) ? &pcmLimiterScale : NULL
);
- if (dmxErr == PCMDMX_INVALID_MODE) {
+ if ( (ErrorStatus == AAC_DEC_OK)
+ && (dmxErr == PCMDMX_INVALID_MODE) ) {
/* Announce the framework that the current combination of channel configuration and downmix
* settings are not know to produce a predictable behavior and thus maybe produce strange output. */
ErrorStatus = AAC_DEC_DECODE_FRAME_ERROR;
@@ -1051,6 +1059,19 @@ bail:
/* Update Statistics */
aacDecoder_UpdateBitStreamCounters(&self->streamInfo, hBs, nBits, ErrorStatus);
+ /* Check whether external output buffer is large enough. */
+ if (timeDataSize_extern < self->streamInfo.numChannels*self->streamInfo.frameSize) {
+ ErrorStatus = AAC_DEC_OUTPUT_BUFFER_TOO_SMALL;
+ }
+
+ /* Update external output buffer. */
+ if ( IS_OUTPUT_VALID(ErrorStatus) ) {
+ FDKmemcpy(pTimeData_extern, pTimeData, self->streamInfo.numChannels*self->streamInfo.frameSize*sizeof(*pTimeData));
+ }
+ else {
+ FDKmemclear(pTimeData_extern, timeDataSize_extern*sizeof(*pTimeData_extern));
+ }
+
return ErrorStatus;
}
@@ -1120,6 +1141,7 @@ LINKSPEC_CPP INT aacDecoder_GetLibInfo ( LIB_INFO *info )
/* Set flags */
info->flags = 0
| CAPF_AAC_LC
+ | CAPF_ER_AAC_SCAL
| CAPF_AAC_VCB11
| CAPF_AAC_HCR
| CAPF_AAC_RVLC
@@ -1130,6 +1152,7 @@ LINKSPEC_CPP INT aacDecoder_GetLibInfo ( LIB_INFO *info )
| CAPF_AAC_MPEG4
+ | CAPF_AAC_DRM_BSFORMAT
| CAPF_AAC_1024
| CAPF_AAC_960
diff --git a/libAACdec/src/block.cpp b/libAACdec/src/block.cpp
index 9d703cc..2965fa6 100644
--- a/libAACdec/src/block.cpp
+++ b/libAACdec/src/block.cpp
@@ -2,7 +2,7 @@
/* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
-© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
+© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved.
1. INTRODUCTION
@@ -324,11 +324,11 @@ AAC_DECODER_ERROR CBlock_ReadSectionData(HANDLE_FDK_BITSTREAM bs,
if (flags & AC_ER_HCR) {
/* HCR input (long) -- collecting sideinfo (for HCR-_long_ only) */
- pNumLinesInSec[numLinesInSecIdx] = BandOffsets[top] - BandOffsets[band];
- numLinesInSecIdx++;
if (numLinesInSecIdx >= MAX_SFB_HCR) {
return AAC_DEC_PARSE_ERROR;
}
+ pNumLinesInSec[numLinesInSecIdx] = BandOffsets[top] - BandOffsets[band];
+ numLinesInSecIdx++;
if (
(sect_cb == BOOKSCL) )
{