From 47c680c62246594107da0a8995c953dfb8040bce Mon Sep 17 00:00:00 2001 From: Jean-Michel Trivi Date: Fri, 27 Dec 2013 16:13:22 -0800 Subject: AAC Decoder: support 6.1/7.1 decoded as 5.1 - Add 6.1 and 7.1 channel support including downmixer. Per default the decoder creates a 5.1 channel output for all streams with more than six encoded channels. Modified file(s): libPCMutils/include/pcmutils_lib.h libPCMutils/src/pcmutils_lib.cpp libAACdec/include/aacdecoder_lib.h libAACdec/src/aac_rom.h libAACdec/src/aacdecoder.cpp libAACdec/src/aac_ram.cpp libAACdec/src/aacdec_drc.cpp libAACdec/src/aacdecoder_lib.cpp libAACdec/src/aac_rom.cpp libAACdec/src/aacdecoder.h libSBRdec/include/sbrdecoder.h libSBRdec/src/sbrdec_drc.h libSBRdec/src/sbrdecoder.cpp libSBRdec/src/sbr_ram.cpp libSBRdec/src/sbr_ram.h libMpegTPDec/include/tp_data.h libMpegTPDec/include/tpdec_lib.h libMpegTPDec/src/version libMpegTPDec/src/tpdec_asc.cpp libMpegTPEnc/include/tp_data.h libMpegTPEnc/src/version libSYS/include/FDK_audio.h libSYS/src/genericStds.cpp - Fix error concealment modules fade-out/in mechanism. Modified file(s): libAACdec/src/conceal.cpp Bug 9428126 Change-Id: I3230bd2072314b730911cd7ec1740e290cb1d254 --- libSBRdec/include/sbrdecoder.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'libSBRdec/include/sbrdecoder.h') diff --git a/libSBRdec/include/sbrdecoder.h b/libSBRdec/include/sbrdecoder.h index 13707e0..cb06dbc 100644 --- a/libSBRdec/include/sbrdecoder.h +++ b/libSBRdec/include/sbrdecoder.h @@ -308,7 +308,7 @@ SBR_ERROR sbrDecoder_Apply ( HANDLE_SBRDECODER self, INT_PCM *timeData, int *numChannels, int *sampleRate, - const UCHAR channelMapping[(6)], + const UCHAR channelMapping[(8)], const int interleaved, const int coreDecodedOk, UCHAR *psDecoded ); -- cgit v1.2.3 From af967fcc55656a0d3c2a05982713f1ca43c1252b Mon Sep 17 00:00:00 2001 From: Jean-Michel Trivi Date: Tue, 20 May 2014 17:24:06 -0700 Subject: AAC Decoder: flush/seek improvements Improve flushing and seeking. Add field to the API stream info structure signaling the additional output delay for flushing and delay compensation. Bug 9428126 Change-Id: I808412905563ea3de50a2e77a9b5dfee829cd2ed --- libAACdec/include/aacdecoder_lib.h | 26 +++++++++++++-------- libAACdec/src/aacdecoder.cpp | 37 ++++++++++++++++++++++------- libAACdec/src/aacdecoder.h | 5 +++- libAACdec/src/aacdecoder_lib.cpp | 14 ++++++++++- libSBRdec/include/sbrdecoder.h | 2 ++ libSBRdec/src/env_extr.h | 2 ++ libSBRdec/src/sbrdecoder.cpp | 48 ++++++++++++++++++++++++++++++++++---- 7 files changed, 108 insertions(+), 26 deletions(-) (limited to 'libSBRdec/include/sbrdecoder.h') diff --git a/libAACdec/include/aacdecoder_lib.h b/libAACdec/include/aacdecoder_lib.h index a281ab9..bf6dcfb 100644 --- a/libAACdec/include/aacdecoder_lib.h +++ b/libAACdec/include/aacdecoder_lib.h @@ -532,18 +532,18 @@ typedef enum */ typedef struct { - /* These three members are the only really relevant ones for the user. */ + /* These five members are the only really relevant ones for the user. */ INT sampleRate; /*!< The samplerate in Hz of the fully decoded PCM audio signal (after SBR processing). */ INT frameSize; /*!< The frame size of the decoded PCM audio signal. \n 1024 or 960 for AAC-LC \n 2048 or 1920 for HE-AAC (v2) \n 512 or 480 for AAC-LD and AAC-ELD */ INT numChannels; /*!< The number of output audio channels in the decoded and interleaved PCM audio signal. */ - AUDIO_CHANNEL_TYPE *pChannelType; /*!< Audio channel type of each output audio channel. */ - UCHAR *pChannelIndices; /*!< Audio channel index for each output audio channel. + AUDIO_CHANNEL_TYPE *pChannelType; /*!< Audio channel type of each output audio channel. */ + UCHAR *pChannelIndices; /*!< Audio channel index for each output audio channel. See ISO/IEC 13818-7:2005(E), 8.5.3.2 Explicit channel mapping using a program_config_element() */ /* Decoder internal members. */ - INT aacSampleRate; /*!< sampling rate in Hz without SBR (from configuration info). */ + INT aacSampleRate; /*!< Sampling rate in Hz without SBR (from configuration info). */ INT profile; /*!< MPEG-2 profile (from file header) (-1: not applicable (e. g. MPEG-4)). */ AUDIO_OBJECT_TYPE aot; /*!< Audio Object Type (from ASC): is set to the appropriate value for MPEG-2 bitstreams (e. g. 2 for AAC-LC). */ INT channelConfig; /*!< Channel configuration (0: PCE defined, 1: mono, 2: stereo, ... */ @@ -556,7 +556,9 @@ typedef struct AUDIO_OBJECT_TYPE extAot; /*!< Extension Audio Object Type (from ASC) */ INT extSamplingRate; /*!< Extension sampling rate in Hz (from ASC) */ - UINT flags; /*!< Copy if internal flags. Only to be written by the decoder, and only to be read externally. */ + UINT outputDelay; /*!< The number of samples the output is additionally delayed by the decoder. */ + + UINT flags; /*!< Copy of internal flags. Only to be written by the decoder, and only to be read externally. */ SCHAR epConfig; /*!< epConfig level (from ASC): only level 0 supported, -1 means no ER (e. g. AOT=2, MPEG-2 AAC, etc.) */ @@ -681,11 +683,15 @@ aacDecoder_Fill ( HANDLE_AACDECODER self, const UINT bufferSize[], UINT *bytesValid ); -#define AACDEC_CONCEAL 1 /*!< Flag for aacDecoder_DecodeFrame(): do not consider new input data. Do concealment. */ -#define AACDEC_FLUSH 2 /*!< Flag for aacDecoder_DecodeFrame(): Do not consider new input data. Flush filterbanks (output delayed audio). */ -#define AACDEC_INTR 4 /*!< Flag for aacDecoder_DecodeFrame(): Signal an input bit stream data discontinuity. Resync any internals as necessary. */ -#define AACDEC_CLRHIST 8 /*!< Flag for aacDecoder_DecodeFrame(): Clear all signal delay lines and history buffers. - Caution: This can cause discontinuities in the output signal. */ +#define AACDEC_CONCEAL 1 /*!< Flag for aacDecoder_DecodeFrame(): Trigger the built-in error concealment module \ + to generate a substitute signal for one lost frame. New input data will not be + considered. */ +#define AACDEC_FLUSH 2 /*!< Flag for aacDecoder_DecodeFrame(): Flush all filterbanks to get all delayed audio \ + without having new input data. Thus new input data will not be considered.*/ +#define AACDEC_INTR 4 /*!< Flag for aacDecoder_DecodeFrame(): Signal an input bit stream data discontinuity. \ + Resync any internals as necessary. */ +#define AACDEC_CLRHIST 8 /*!< Flag for aacDecoder_DecodeFrame(): Clear all signal delay lines and history buffers.\ + CAUTION: This can cause discontinuities in the output signal. */ /** * \brief Decode one audio frame diff --git a/libAACdec/src/aacdecoder.cpp b/libAACdec/src/aacdecoder.cpp index 18c9afa..15b47ab 100644 --- a/libAACdec/src/aacdecoder.cpp +++ b/libAACdec/src/aacdecoder.cpp @@ -717,6 +717,8 @@ void CStreamInfoInit(CStreamInfo *pStreamInfo) pStreamInfo->numChannels = 0; pStreamInfo->sampleRate = 0; pStreamInfo->frameSize = 0; + + pStreamInfo->outputDelay = 0; } /*! @@ -1184,11 +1186,8 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame( CConcealment_InitChannelData(&self->pAacDecoderStaticChannelInfo[ch]->concealmentInfo, &self->concealCommonData, self->streamInfo.aacSamplesPerFrame ); - /* Clear concealment buffers to get rid of the complete history */ - FDKmemclear(self->pAacDecoderStaticChannelInfo[ch]->concealmentInfo.spectralCoefficient, 1024 * sizeof(FIXP_CNCL)); - FDKmemclear(self->pAacDecoderStaticChannelInfo[ch]->concealmentInfo.specScale, 8 * sizeof(SHORT)); /* Clear overlap-add buffers to avoid clicks. */ - FDKmemclear(self->pAacDecoderStaticChannelInfo[ch]->IMdct.overlap.freq, OverlapBufferSize*sizeof(FIXP_DBL)); + FDKmemclear(self->pAacDecoderStaticChannelInfo[ch]->pOverlapBuffer, OverlapBufferSize*sizeof(FIXP_DBL)); } } @@ -1508,10 +1507,19 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame( break; } } - if (err == SBRDEC_OK) { + switch (err) { + case SBRDEC_PARSE_ERROR: + /* Can not go on parsing because we do not + know the length of the SBR extension data. */ + FDKpushFor(bs, bitCnt); + bitCnt = 0; + break; + case SBRDEC_OK: self->sbrEnabled = 1; - } else { + break; + default: self->frameOK = 0; + break; } } @@ -1601,13 +1609,17 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame( self->frameOK=0; } - /* store or restore the number of channels */ + /* store or restore the number of channels and the corresponding info */ if ( self->frameOK && !(flags &(AACDEC_CONCEAL|AACDEC_FLUSH)) ) { - self->concealChannels = aacChannels; /* store */ + self->aacChannelsPrev = aacChannels; /* store */ + FDKmemcpy(self->channelTypePrev, self->channelType, (8)*sizeof(AUDIO_CHANNEL_TYPE)); /* store */ + FDKmemcpy(self->channelIndicesPrev, self->channelIndices, (8)*sizeof(UCHAR)); /* store */ self->sbrEnabledPrev = self->sbrEnabled; } else { if (self->aacChannels > 0) { - aacChannels = self->concealChannels; /* restore */ + aacChannels = self->aacChannelsPrev; /* restore */ + FDKmemcpy(self->channelType, self->channelTypePrev, (8)*sizeof(AUDIO_CHANNEL_TYPE)); /* restore */ + FDKmemcpy(self->channelIndices, self->channelIndicesPrev, (8)*sizeof(UCHAR)); /* restore */ self->sbrEnabled = self->sbrEnabledPrev; } } @@ -1687,6 +1699,11 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame( } + if ( flags&AACDEC_FLUSH ) { + /* Clear pAacDecoderChannelInfo->pSpectralCoefficient because with AACDEC_FLUSH set it contains undefined data. */ + FDKmemclear(pAacDecoderChannelInfo->pSpectralCoefficient, sizeof(FIXP_DBL)*self->streamInfo.aacSamplesPerFrame); + } + /* Conceal defective spectral data */ @@ -1765,6 +1782,8 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame( ); } + /* Add additional concealment delay */ + self->streamInfo.outputDelay += CConcealment_GetDelay(&self->concealCommonData) * self->streamInfo.aacSamplesPerFrame; /* Reorder channel type information tables. */ { diff --git a/libAACdec/src/aacdecoder.h b/libAACdec/src/aacdecoder.h index bcbc040..3541773 100644 --- a/libAACdec/src/aacdecoder.h +++ b/libAACdec/src/aacdecoder.h @@ -198,7 +198,10 @@ struct AAC_DECODER_INSTANCE { CAacDecoderCommonData aacCommonData; /*!< Temporal shared data for all channels hooked into pAacDecoderChannelInfo */ CConcealParams concealCommonData; - INT concealChannels; + + INT aacChannelsPrev; /*!< The amount of AAC core channels of the last successful decode call. */ + AUDIO_CHANNEL_TYPE channelTypePrev[(8)]; /*!< Array holding the channelType values of the last successful decode call. */ + UCHAR channelIndicesPrev[(8)]; /*!< Array holding the channelIndices values of the last successful decode call. */ HANDLE_SBRDECODER hSbrDecoder; /*!< SBR decoder handle. */ diff --git a/libAACdec/src/aacdecoder_lib.cpp b/libAACdec/src/aacdecoder_lib.cpp index 98ef0de..e2c757a 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 7 +#define AACDECODER_LIB_VL2 8 #define AACDECODER_LIB_TITLE "AAC Decoder Lib" #define AACDECODER_LIB_BUILD_DATE __DATE__ #define AACDECODER_LIB_BUILD_TIME __TIME__ @@ -842,6 +842,7 @@ LINKSPEC_CPP AAC_DECODER_ERROR aacDecoder_DecodeFrame( /* Signal bit stream interruption to other modules if required. */ if ( fTpInterruption || (flags & (AACDEC_INTR|AACDEC_CLRHIST)) ) { + sbrDecoder_SetParam(self->hSbrDecoder, SBR_CLEAR_HISTORY, (flags&AACDEC_CLRHIST)); aacDecoder_SignalInterruption(self); if ( ! (flags & AACDEC_INTR) ) { ErrorStatus = AAC_DEC_TRANSPORT_SYNC_ERROR; @@ -857,6 +858,8 @@ LINKSPEC_CPP AAC_DECODER_ERROR aacDecoder_DecodeFrame( self->streamInfo.numBadBytes = 0; self->streamInfo.numTotalBytes = 0; } + /* Reset the output delay field. The modules will add their figures one after another. */ + self->streamInfo.outputDelay = 0; if (self->limiterEnableUser==(UCHAR)-1) { /* Enbale limiter for all non-lowdelay AOT's. */ @@ -916,6 +919,9 @@ LINKSPEC_CPP AAC_DECODER_ERROR aacDecoder_DecodeFrame( sbrDecoder_SetParam ( self->hSbrDecoder, SBR_SYSTEM_BITSTREAM_DELAY, self->sbrParams.bsDelay); + sbrDecoder_SetParam ( self->hSbrDecoder, + SBR_FLUSH_DATA, + (flags & AACDEC_FLUSH) ); if ( self->streamInfo.aot == AOT_ER_AAC_ELD ) { /* Configure QMF */ @@ -958,6 +964,9 @@ LINKSPEC_CPP AAC_DECODER_ERROR aacDecoder_DecodeFrame( self->streamInfo.frameSize = self->streamInfo.aacSamplesPerFrame << 1; } } + /* Correct the additional concealment delay figures */ + self->streamInfo.outputDelay -= self->sbrParams.bsDelay * self->streamInfo.aacSamplesPerFrame; + self->streamInfo.outputDelay += self->sbrParams.bsDelay * self->streamInfo.frameSize; if (self->psPossible) { self->flags |= AC_PS_PRESENT; @@ -1014,6 +1023,9 @@ LINKSPEC_CPP AAC_DECODER_ERROR aacDecoder_DecodeFrame( self->extGainDelay, self->streamInfo.frameSize ); + + /* Announce the additional limiter output delay */ + self->streamInfo.outputDelay += getLimiterDelay(self->hLimiter); } } diff --git a/libSBRdec/include/sbrdecoder.h b/libSBRdec/include/sbrdecoder.h index cb06dbc..36a4739 100644 --- a/libSBRdec/include/sbrdecoder.h +++ b/libSBRdec/include/sbrdecoder.h @@ -145,6 +145,8 @@ typedef enum SBR_SYSTEM_BITSTREAM_DELAY, /*!< System: Switch to enable an additional SBR bitstream delay of one frame. */ SBR_QMF_MODE, /*!< Set QMF mode, either complex or low power. */ SBR_LD_QMF_TIME_ALIGN, /*!< Set QMF type, either LD-MPS or CLDFB. Relevant for ELD streams only. */ + SBR_FLUSH_DATA, /*!< Set internal state to flush the decoder with the next process call. */ + SBR_CLEAR_HISTORY, /*!< Clear all internal states (delay lines, QMF states, ...). */ SBR_BS_INTERRUPTION /*!< Signal bit stream interruption. Value is ignored. */ } SBRDEC_PARAM; diff --git a/libSBRdec/src/env_extr.h b/libSBRdec/src/env_extr.h index 5db6d3d..ddbfa18 100644 --- a/libSBRdec/src/env_extr.h +++ b/libSBRdec/src/env_extr.h @@ -179,6 +179,8 @@ typedef FREQ_BAND_DATA *HANDLE_FREQ_BAND_DATA; #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_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. */ #define SBRDEC_HDR_STAT_RESET 1 #define SBRDEC_HDR_STAT_UPDATE 2 diff --git a/libSBRdec/src/sbrdecoder.cpp b/libSBRdec/src/sbrdecoder.cpp index 5734020..bed23c7 100644 --- a/libSBRdec/src/sbrdecoder.cpp +++ b/libSBRdec/src/sbrdecoder.cpp @@ -137,7 +137,7 @@ amm-info@iis.fraunhofer.de /* Decoder library info */ #define SBRDECODER_LIB_VL0 2 #define SBRDECODER_LIB_VL1 2 -#define SBRDECODER_LIB_VL2 4 +#define SBRDECODER_LIB_VL2 5 #define SBRDECODER_LIB_TITLE "SBR Decoder" #define SBRDECODER_LIB_BUILD_DATE __DATE__ #define SBRDECODER_LIB_BUILD_TIME __TIME__ @@ -444,6 +444,7 @@ SBR_ERROR sbrDecoder_InitElement ( && self->coreCodec == coreCodec && self->pSbrElement[elementIndex] != NULL && self->pSbrElement[elementIndex]->elementID == elementID + && !(self->flags & SBRDEC_FORCE_RESET) ) { /* Nothing to do */ @@ -550,8 +551,9 @@ bail: if (nSbrElementsStart < self->numSbrElements) { /* Free the memory allocated for this element */ sbrDecoder_DestroyElement( self, elementIndex ); - } else if (self->pSbrElement[elementIndex] != NULL) { - /* Set error flag to trigger concealment */ + } else if ( (self->pSbrElement[elementIndex] != NULL) + && (elementIndex < (8))) + { /* Set error flag to trigger concealment */ self->pSbrElement[elementIndex]->frameErrorFlag[self->pSbrElement[elementIndex]->useFrameSlot] = 1; } } @@ -728,6 +730,24 @@ SBR_ERROR sbrDecoder_SetParam (HANDLE_SBRDECODER self, } } break; + case SBR_FLUSH_DATA: + if (value != 0) { + if (self == NULL) { + errorStatus = SBRDEC_NOT_INITIALIZED; + } else { + self->flags |= SBRDEC_FLUSH; + } + } + break; + case SBR_CLEAR_HISTORY: + if (value != 0) { + if (self == NULL) { + errorStatus = SBRDEC_NOT_INITIALIZED; + } else { + self->flags |= SBRDEC_FORCE_RESET; + } + } + break; case SBR_BS_INTERRUPTION: { int elementIndex; @@ -738,7 +758,8 @@ SBR_ERROR sbrDecoder_SetParam (HANDLE_SBRDECODER self, } /* Loop over SBR elements */ - for (elementIndex = 0; elementIndex < self->numSbrElements; elementIndex++) + for (elementIndex = 0; elementIndex < self->numSbrElements; elementIndex++) { + if (self->pSbrElement[elementIndex] != NULL) { HANDLE_SBR_HEADER_DATA hSbrHeader; int headerIndex = getHeaderSlot(self->pSbrElement[elementIndex]->useFrameSlot, @@ -750,7 +771,7 @@ SBR_ERROR sbrDecoder_SetParam (HANDLE_SBRDECODER self, This switches off bitstream parsing until a new header arrives. */ hSbrHeader->syncState = UPSAMPLING; hSbrHeader->status |= SBRDEC_HDR_STAT_UPDATE; - } + } } } break; default: @@ -1119,6 +1140,10 @@ SBR_ERROR sbrDecoder_Parse( } } } + } else { + /* The returned bit count will not be the actual payload size since we did not + parse the frame data. Return an error so that the caller can react respectively. */ + errorStatus = SBRDEC_PARSE_ERROR; } if (!fDoDecodeSbrData) { @@ -1198,6 +1223,15 @@ sbrDecoder_DecodeElement ( int stereo = (hSbrElement->elementID == ID_CPE) ? 1 : 0; int numElementChannels = hSbrElement->nChannels; /* Number of channels of the current SBR element */ + if (self->flags & SBRDEC_FLUSH) { + /* Move frame pointer to the next slot which is up to be decoded/applied next */ + hSbrElement->useFrameSlot = (hSbrElement->useFrameSlot+1) % (self->numDelayFrames+1); + /* Update header and frame data pointer because they have already been set */ + hSbrHeader = &self->sbrHeader[elementIndex][hSbrElement->useHeaderSlot[hSbrElement->useFrameSlot]]; + hFrameDataLeft = &hSbrElement->pSbrChannel[0]->frameData[hSbrElement->useFrameSlot]; + hFrameDataRight = &hSbrElement->pSbrChannel[1]->frameData[hSbrElement->useFrameSlot]; + } + /* Update the header error flag */ hSbrHeader->frameErrorFlag = hSbrElement->frameErrorFlag[hSbrElement->useFrameSlot]; @@ -1472,6 +1506,10 @@ SBR_ERROR sbrDecoder_Apply ( HANDLE_SBRDECODER self, + /* Clear reset and flush flag because everything seems to be done successfully. */ + self->flags &= ~SBRDEC_FORCE_RESET; + self->flags &= ~SBRDEC_FLUSH; + bail: return errorStatus; -- cgit v1.2.3 From 6792cf6361ff339e336287affb0bfe54bf6957a9 Mon Sep 17 00:00:00 2001 From: Jean-Michel Trivi Date: Tue, 20 May 2014 17:39:03 -0700 Subject: 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 --- libAACdec/src/aacdecoder_lib.cpp | 15 +++++++++------ libSBRdec/include/sbrdecoder.h | 7 +++++++ libSBRdec/src/env_extr.h | 1 + libSBRdec/src/sbrdecoder.cpp | 35 ++++++++++++++++++++++++++++++++++- libSYS/include/FDK_audio.h | 8 ++++++++ libSYS/src/genericStds.cpp | 2 +- 6 files changed, 60 insertions(+), 8 deletions(-) (limited to 'libSBRdec/include/sbrdecoder.h') 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 @@ amm-info@iis.fraunhofer.de /* 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 @@ LINKSPEC_CPP AAC_DECODER_ERROR aacDecoder_DecodeFrame( if (sbrError == SBRDEC_OK) { + #define UPS_SCALE 2 /* Maximum upsampling factor is 4 (CELP+SBR) */ + FIXP_DBL upsampleFactor = FL2FXCONST_DBL(1.0f/(1<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<streamInfo.frameSize = self->streamInfo.aacSamplesPerFrame << 1; + upsampleFactor = FL2FXCONST_DBL(2.0f/(1<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<streamInfo.outputDelay = (UINT)(INT)fMult((FIXP_DBL)self->streamInfo.outputDelay<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 @@ SBR_ERROR sbrDecoder_Close ( HANDLE_SBRDECODER *self ); */ 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 @@ typedef FREQ_BAND_DATA *HANDLE_FREQ_BAND_DATA; #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 @@ amm-info@iis.fraunhofer.de /* 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 @@ SBR_ERROR sbrDecoder_ResetElement ( if ( sampleRateIn == sampleRateOut ) { synDownsampleFac = 2; + self->flags |= SBRDEC_DOWNSAMPLE; } else { synDownsampleFac = 1; + self->flags &= ~SBRDEC_DOWNSAMPLE; } self->synDownsampleFac = synDownsampleFac; @@ -1582,3 +1584,34 @@ INT sbrDecoder_GetLibInfo( LIB_INFO *info ) 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 @@ typedef enum } 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 @@ amm-info@iis.fraunhofer.de /* 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__ -- cgit v1.2.3