From 203e3f28fbebec7011342017fafc2a0bda0ce530 Mon Sep 17 00:00:00 2001 From: Jean-Michel Trivi Date: Fri, 8 Apr 2016 12:05:12 -0700 Subject: 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 --- libAACdec/include/aacdecoder_lib.h | 3 +- libAACdec/src/aac_rom.cpp | 85 ++++++++++++++++++++++++++++++++------ libAACdec/src/aacdecoder.cpp | 37 ++++++++++++++--- libAACdec/src/aacdecoder.h | 4 +- libAACdec/src/aacdecoder_lib.cpp | 43 ++++++++++++++----- libAACdec/src/block.cpp | 6 +-- 6 files changed, 145 insertions(+), 33 deletions(-) (limited to 'libAACdec') diff --git a/libAACdec/include/aacdecoder_lib.h b/libAACdec/include/aacdecoder_lib.h index a0c0854..7ab60f1 100644 --- a/libAACdec/include/aacdecoder_lib.h +++ b/libAACdec/include/aacdecoder_lib.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 @@ -378,6 +378,7 @@ typedef enum { not exist. */ AAC_DEC_NEED_TO_RESTART = 0x200B, /*!< The decoder needs to be restarted, since the requiered configuration change cannot be performed. */ + AAC_DEC_OUTPUT_BUFFER_TOO_SMALL = 0x200C, /*!< The provided output buffer is too small. */ aac_dec_init_error_end = 0x2FFF, /* Decode errors. Output buffer is valid but concealed. */ 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) ) { -- cgit v1.2.3