From e46ff0f7f92fd4be35afc78050f01210a375fbb7 Mon Sep 17 00:00:00 2001 From: Jean-Michel Trivi Date: Mon, 21 Mar 2016 14:12:19 -0700 Subject: Fix stack corruption happening in aacDecoder_drcExtractAndMap() In the aacDecoder_drcExtractAndMap() function, self->numThreads can be used after having exceeded its intended max value, MAX_DRC_THREADS, causing memory to be cleared after the threadBs[MAX_DRC_THREADS] array. The crash is prevented by never using self->numThreads with a value equal to or greater than MAX_DRC_THREADS. A proper fix will be required as there seems to be an issue as to which entry in the threadBs array is meant to be initialized and used. Bug 26751339 Change-Id: I655cc40c35d4206ab72e83b2bdb751be2fe52b5a --- libAACdec/src/aacdec_drc.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'libAACdec') diff --git a/libAACdec/src/aacdec_drc.cpp b/libAACdec/src/aacdec_drc.cpp index 0c33a2b..9cfc5d5 100644 --- a/libAACdec/src/aacdec_drc.cpp +++ b/libAACdec/src/aacdec_drc.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 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -705,6 +705,10 @@ static int aacDecoder_drcExtractAndMap ( } self->numPayloads = 0; + if (self->numThreads >= MAX_DRC_THREADS) { + self->numThreads = MAX_DRC_THREADS - 1; + } + if (self->dvbAncDataAvailable) { /* Append a DVB heavy compression payload thread if available. */ int bitsParsed; @@ -731,6 +735,10 @@ static int aacDecoder_drcExtractAndMap ( /* coupling channels not supported */ + if (self->numThreads >= MAX_DRC_THREADS) { + self->numThreads = MAX_DRC_THREADS - 1; + } + /* check for valid threads */ for (thread = 0; thread < self->numThreads; thread++) { CDrcPayload *pThreadBs = &threadBs[thread]; -- cgit v1.2.3 From e1c78ed73faa51f2c7fcb0c4a17a92be9cc747f5 Mon Sep 17 00:00:00 2001 From: Jean-Michel Trivi Date: Mon, 4 Apr 2016 16:06:48 -0700 Subject: SBR/AAC encoder updates, code clean up * SBR-Encoder - Prevent noise level overflow in noise floor detection. - Saturate threshold calculation in transient detection. Modified file(s): libSBRenc/src/nf_est.cpp libSBRenc/src/sbr_encoder.cpp libSBRenc/src/tran_det.cpp * AAC-Encoder - Expand input data range of GetInvInt() function. There was an encoder assert observed in non-default bitrate configuration. Modified file(s): libAACenc/src/aacenc_lib.cpp libAACenc/src/intensity.cpp libFDK/include/fixpoint_math.h libFDK/src/FDK_core.cpp libFDK/src/FDK_tools_rom.cpp - Make sure that the encoder is stable with regard to very low audio bandwidth confguration parameter value. - Fix lowdelay blending for low audio bandwidth. Modified file(s): libAACenc/src/aacenc.cpp libAACenc/src/aacenc_lib.cpp libAACenc/src/adj_thr.cpp libAACenc/src/psy_configuration.cpp libAACenc/src/psy_main.cpp - Disable pseudo surround flag in case metadata matrix mixdown index is present in program config element. Modified file(s): libAACenc/src/aacenc_lib.cpp - Enable variable bitrate mode in encoder api. - Add AACENC_PEAK_BITRATE parameter to encoder api. - Add AACENC_AUDIOMUXVER parameter to encoder api. Modified file(s): libAACenc/include/aacenc_lib.h libAACenc/src/aacenc.cpp libAACenc/src/aacenc.h libAACenc/src/aacenc_lib.cpp libAACenc/src/qc_main.cpp libMpegTPEnc/src/tpenc_latm.cpp libMpegTPEnc/src/version * FDK-Sources - Code clean up. Remove unneeded pseudo audio object types and transport types. Modified file(s): libAACdec/src/aacdecoder.cpp libAACdec/src/aacdecoder_lib.cpp libAACenc/include/aacenc_lib.h libAACenc/src/aacenc.cpp libAACenc/src/aacenc_lib.cpp libFDK/src/FDK_tools_rom.cpp libMpegTPDec/src/tpdec_lib.cpp libMpegTPDec/src/version libMpegTPEnc/src/tpenc_latm.cpp libMpegTPEnc/src/version libSBRdec/src/sbrdecoder.cpp libSBRenc/src/sbr_encoder.cpp libSYS/include/FDK_audio.h libSYS/src/genericStds.cpp Change-Id: I807a53cb7f48c9ee7563cb8da1d0c52221576ca6 --- documentation/aacEncoder.pdf | Bin 518665 -> 381677 bytes libAACdec/src/aacdecoder.cpp | 17 +----- libAACdec/src/aacdecoder_lib.cpp | 4 +- libAACenc/include/aacenc_lib.h | 23 +++++--- libAACenc/src/aacenc.cpp | 83 ++++++++++++++++++----------- libAACenc/src/aacenc.h | 34 +++++++++++- libAACenc/src/aacenc_lib.cpp | 101 ++++++++++++++++++++---------------- libAACenc/src/adj_thr.cpp | 2 +- libAACenc/src/intensity.cpp | 3 +- libAACenc/src/psy_configuration.cpp | 5 +- libAACenc/src/psy_main.cpp | 2 +- libAACenc/src/qc_main.cpp | 4 ++ libFDK/include/fixpoint_math.h | 12 ++--- libFDK/src/FDK_core.cpp | 2 +- libFDK/src/FDK_tools_rom.cpp | 32 ++++-------- libMpegTPDec/src/tpdec_lib.cpp | 3 +- libMpegTPDec/src/version | 2 +- libMpegTPEnc/src/tpenc_latm.cpp | 27 +++++----- libMpegTPEnc/src/version | 2 +- libSBRdec/src/sbrdecoder.cpp | 6 +-- libSBRenc/src/nf_est.cpp | 7 +-- libSBRenc/src/sbr_encoder.cpp | 10 +--- libSBRenc/src/tran_det.cpp | 13 ++--- libSYS/include/FDK_audio.h | 44 ++++------------ libSYS/src/genericStds.cpp | 4 +- 25 files changed, 227 insertions(+), 215 deletions(-) (limited to 'libAACdec') diff --git a/documentation/aacEncoder.pdf b/documentation/aacEncoder.pdf index e8420b1..efb1858 100644 Binary files a/documentation/aacEncoder.pdf and b/documentation/aacEncoder.pdf differ diff --git a/libAACdec/src/aacdecoder.cpp b/libAACdec/src/aacdecoder.cpp index e19c501..8270f69 100644 --- a/libAACdec/src/aacdecoder.cpp +++ b/libAACdec/src/aacdecoder.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 @@ -159,21 +159,6 @@ amm-info@iis.fraunhofer.de -#define CAN_DO_PS(aot) \ - ((aot) == AOT_AAC_LC \ -|| (aot) == AOT_SBR \ -|| (aot) == AOT_PS \ -|| (aot) == AOT_ER_BSAC \ -|| (aot) == AOT_DRM_AAC) - -#define IS_USAC(aot) \ - ((aot) == AOT_USAC \ -|| (aot) == AOT_RSVD50) - -#define IS_LOWDELAY(aot) \ - ((aot) == AOT_ER_AAC_LD \ -|| (aot) == AOT_ER_AAC_ELD) - void CAacDecoder_SyncQmfMode(HANDLE_AACDECODER self) { diff --git a/libAACdec/src/aacdecoder_lib.cpp b/libAACdec/src/aacdecoder_lib.cpp index 94eb3c0..b501eb9 100644 --- a/libAACdec/src/aacdecoder_lib.cpp +++ b/libAACdec/src/aacdecoder_lib.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 @@ -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 10 +#define AACDECODER_LIB_VL2 11 #define AACDECODER_LIB_TITLE "AAC Decoder Lib" #ifdef __ANDROID__ #define AACDECODER_LIB_BUILD_DATE "" diff --git a/libAACenc/include/aacenc_lib.h b/libAACenc/include/aacenc_lib.h index 8c0e1cd..828a917 100644 --- a/libAACenc/include/aacenc_lib.h +++ b/libAACenc/include/aacenc_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 @@ -897,11 +897,7 @@ typedef enum This configuration can be used only with stereo input audio data. - 23: MPEG-4 AAC Low-Delay. - 39: MPEG-4 AAC Enhanced Low-Delay. Since there is no ::AUDIO_OBJECT_TYPE for ELD in - combination with SBR defined, enable SBR explicitely by ::AACENC_SBR_MODE parameter. - - 129: MPEG-2 AAC Low Complexity. - - 132: MPEG-2 AAC Low Complexity with Spectral Band Replication (HE-AAC). - - 156: MPEG-2 AAC Low Complexity with Spectral Band Replication and Parametric Stereo (HE-AAC v2). - This configuration can be used only with stereo input audio data. */ + combination with SBR defined, enable SBR explicitely by ::AACENC_SBR_MODE parameter. */ AACENC_BITRATE = 0x0101, /*!< Total encoder bitrate. This parameter is mandatory and interacts with ::AACENC_BITRATEMODE. - CBR: Bitrate in bits/second. @@ -958,6 +954,16 @@ typedef enum - 1 to fs/2: Frequency bandwidth in Hertz. (Experts only, better do not touch this value to avoid degraded audio quality) */ + AACENC_PEAK_BITRATE = 0x0207, /*!< Peak bitrate configuration parameter to adjust maximum bits per audio frame. Bitrate is in bits/second. + The peak bitrate will internally be limited to the chosen bitrate ::AACENC_BITRATE as lower limit + and the number_of_effective_channels*6144 bit as upper limit. + + Setting the peak bitrate equal to ::AACENC_BITRATE does not necessarily mean that the audio frames + will be of constant size. Since the peak bitate is in bits/second, the frame sizes can vary by + one byte in one or the other direction over various frames. However, it is not recommended to reduce + the peak pitrate to ::AACENC_BITRATE - it would disable the bitreservoir, which would affect the + audio quality by a large amount. */ + AACENC_TRANSMUX = 0x0300, /*!< Transport type to be used. See ::TRANSPORT_TYPE in FDK_audio.h. Following types can be configured in encoder library: - 0: raw access units @@ -1023,6 +1029,11 @@ typedef enum - ADTS: Maximum number of sub frames restricted to 4. - LOAS/LATM: Maximum number of sub frames restricted to 2.*/ + AACENC_AUDIOMUXVER = 0x0304, /*!< AudioMuxVersion to be used for LATM. (AudioMuxVersionA, currently not implemented): + - 0: Default, no transmission of tara Buffer fullness, no ASC length and including actual latm Buffer fullnes. + - 1: Transmission of tara Buffer fullness, ASC length and actual latm Buffer fullness. + - 2: Transmission of tara Buffer fullness, ASC length and maximum level of latm Buffer fullness. */ + AACENC_PROTECTION = 0x0306, /*!< Configure protection in tranpsort layer: - 0: No protection. (default) - 1: CRC active for ADTS bitstream format. */ diff --git a/libAACenc/src/aacenc.cpp b/libAACenc/src/aacenc.cpp index c47e882..5e8c08d 100644 --- a/libAACenc/src/aacenc.cpp +++ b/libAACenc/src/aacenc.cpp @@ -107,6 +107,39 @@ amm-info@iis.fraunhofer.de #define MIN_BUFSIZE_PER_EFF_CHAN 6144 +INT FDKaacEnc_CalcBitsPerFrame( + const INT bitRate, + const INT frameLength, + const INT samplingRate + ) +{ + int shift = 0; + while ((frameLength & ~((1 << (shift + 1)) - 1)) == frameLength + && (samplingRate & ~((1 << (shift + 1)) - 1)) == samplingRate) + { + shift++; + } + + return (bitRate*(frameLength>>shift)) / (samplingRate>>shift); +} + +INT FDKaacEnc_CalcBitrate( + const INT bitsPerFrame, + const INT frameLength, + const INT samplingRate + ) +{ + int shift = 0; + while ((frameLength & ~((1 << (shift + 1)) - 1)) == frameLength + && (samplingRate & ~((1 << (shift + 1)) - 1)) == samplingRate) + { + shift++; + } + + return (bitsPerFrame * (samplingRate>>shift)) / ( frameLength>>shift) ; + +} + static AAC_ENCODER_ERROR FDKaacEnc_InitCheckAncillary(INT bitRate, INT framelength, INT ancillaryRate, @@ -220,21 +253,19 @@ INT FDKaacEnc_GetVBRBitrate(INT bitrateMode, CHANNEL_MODE channelMode) /** * \brief Convert encoder bitreservoir value for transport library. * - * \param bitrateMode Bitratemode used in current encoder instance. Se ::AACENC_BITRATE_MODE - * \param bitresTotal Encoder bitreservoir level in bits. + * \param hAacEnc Encoder handle * * \return Corrected bitreservoir level used in transport library. */ static INT FDKaacEnc_EncBitresToTpBitres( - const AACENC_BITRATE_MODE bitrateMode, - const INT bitresTotal + const HANDLE_AAC_ENC hAacEnc ) { INT transporBitreservoir = 0; - switch (bitrateMode) { + switch (hAacEnc->bitrateMode) { case AACENC_BR_MODE_CBR: - transporBitreservoir = bitresTotal; /* encoder bitreservoir level */ + transporBitreservoir = hAacEnc->qcKernel->bitResTot; /* encoder bitreservoir level */ break; case AACENC_BR_MODE_VBR_1: case AACENC_BR_MODE_VBR_2: @@ -253,6 +284,10 @@ static INT FDKaacEnc_EncBitresToTpBitres( FDK_ASSERT(0); } + if (hAacEnc->config->audioMuxVersion==2) { + transporBitreservoir = MIN_BUFSIZE_PER_EFF_CHAN * hAacEnc->channelMapping.nChannelsEff; + } + return transporBitreservoir; } @@ -289,6 +324,7 @@ void FDKaacEnc_AacInitDefaultConfig(AACENC_CONFIG *config) config->minBitsPerFrame = -1; /* minum number of bits in each AU */ config->maxBitsPerFrame = -1; /* minum number of bits in each AU */ config->bitreservoir = -1; /* default, uninitialized value */ + config->audioMuxVersion = -1; /* audio mux version not configured */ /* init tabs in fixpoint_math */ InitLdInt(); @@ -564,7 +600,10 @@ AAC_ENCODER_ERROR FDKaacEnc_Initialize(HANDLE_AAC_ENC hAacEnc, qcInit.averageBits = (averageBitsPerFrame+7)&~7; qcInit.bitRes = MIN_BUFSIZE_PER_EFF_CHAN*cm->nChannelsEff; qcInit.maxBits = MIN_BUFSIZE_PER_EFF_CHAN*cm->nChannelsEff; - qcInit.minBits = 0; + qcInit.maxBits = (config->maxBitsPerFrame!=-1) ? fixMin(qcInit.maxBits, config->maxBitsPerFrame) : qcInit.maxBits; + qcInit.maxBits = fixMax(qcInit.maxBits, (averageBitsPerFrame+7)&~7); + qcInit.minBits = (config->minBitsPerFrame!=-1) ? config->minBitsPerFrame : 0; + qcInit.minBits = fixMin(qcInit.minBits, averageBitsPerFrame&~7); } else { @@ -575,9 +614,11 @@ AAC_ENCODER_ERROR FDKaacEnc_Initialize(HANDLE_AAC_ENC hAacEnc, qcInit.maxBits = fixMin(MIN_BUFSIZE_PER_EFF_CHAN*cm->nChannelsEff, ((averageBitsPerFrame+7)&~7)+qcInit.bitRes); qcInit.maxBits = (config->maxBitsPerFrame!=-1) ? fixMin(qcInit.maxBits, config->maxBitsPerFrame) : qcInit.maxBits; + qcInit.maxBits = fixMin(MIN_BUFSIZE_PER_EFF_CHAN*cm->nChannelsEff, fixMax(qcInit.maxBits, (averageBitsPerFrame+7+8)&~7)); qcInit.minBits = fixMax(0, ((averageBitsPerFrame-1)&~7)-qcInit.bitRes-transportEnc_GetStaticBits(hTpEnc, ((averageBitsPerFrame+7)&~7)+qcInit.bitRes)); qcInit.minBits = (config->minBitsPerFrame!=-1) ? fixMax(qcInit.minBits, config->minBitsPerFrame) : qcInit.minBits; + qcInit.minBits = fixMin(qcInit.minBits, (averageBitsPerFrame - transportEnc_GetStaticBits(hTpEnc, qcInit.maxBits))&~7); } qcInit.sampleRate = config->sampleRate; @@ -585,11 +626,9 @@ AAC_ENCODER_ERROR FDKaacEnc_Initialize(HANDLE_AAC_ENC hAacEnc, qcInit.nSubFrames = config->nSubFrames; qcInit.padding.paddingRest = config->sampleRate; - /* Calc meanPe */ - bw_ratio = fDivNorm((FIXP_DBL)hAacEnc->bandwidth90dB, (FIXP_DBL)(config->sampleRate>>1), &qbw); - qbw = DFRACT_BITS-1-qbw; - /* qcInit.meanPe = 10.0f * FRAME_LEN_LONG * hAacEnc->bandwidth90dB/(config->sampleRate/2.0f); */ - qcInit.meanPe = fMult(bw_ratio, (FIXP_DBL)((10*config->framelength)<<16)) >> (qbw-15); + /* Calc meanPe: qcInit.meanPe = 10.0f * FRAME_LEN_LONG * hAacEnc->bandwidth90dB/(config->sampleRate/2.0f); */ + bw_ratio = fDivNorm((FIXP_DBL)(10*config->framelength*hAacEnc->bandwidth90dB), (FIXP_DBL)(config->sampleRate), &qbw); + qcInit.meanPe = FDKmax((INT)scaleValue(bw_ratio, qbw+1-(DFRACT_BITS-1)), 1); /* Calc maxBitFac */ mbfac = fDivNorm((MIN_BUFSIZE_PER_EFF_CHAN-744)*cm->nChannelsEff, qcInit.averageBits/qcInit.nSubFrames, &qmbfac); @@ -651,23 +690,7 @@ AAC_ENCODER_ERROR FDKaacEnc_Initialize(HANDLE_AAC_ENC hAacEnc, if (ErrorStatus != AAC_ENC_OK) goto bail; - /* Map virtual aot's to intern aot used in bitstream writer. */ - switch (hAacEnc->config->audioObjectType) { - case AOT_MP2_AAC_LC: - case AOT_DABPLUS_AAC_LC: - hAacEnc->aot = AOT_AAC_LC; - break; - case AOT_MP2_SBR: - case AOT_DABPLUS_SBR: - hAacEnc->aot = AOT_SBR; - break; - case AOT_MP2_PS: - case AOT_DABPLUS_PS: - hAacEnc->aot = AOT_PS; - break; - default: - hAacEnc->aot = hAacEnc->config->audioObjectType; - } + hAacEnc->aot = hAacEnc->config->audioObjectType; /* common things */ @@ -932,7 +955,7 @@ AAC_ENCODER_ERROR FDKaacEnc_EncodeFrame( HANDLE_AAC_ENC hAacEnc, transportEnc_WriteAccessUnit( hTpEnc, totalBits, - FDKaacEnc_EncBitresToTpBitres(hAacEnc->bitrateMode, hAacEnc->qcKernel->bitResTot), + FDKaacEnc_EncBitresToTpBitres(hAacEnc), cm->nChannelsEff); /* write bitstream */ diff --git a/libAACenc/src/aacenc.h b/libAACenc/src/aacenc.h index 87fc3e8..61520de 100644 --- a/libAACenc/src/aacenc.h +++ b/libAACenc/src/aacenc.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 @@ -204,6 +204,8 @@ struct AACENC_CONFIG { INT maxBitsPerFrame; /* maximum number of bits in AU */ INT bitreservoir; /* size of bitreservoir */ + INT audioMuxVersion; /* audio mux version in loas/latm transport format */ + UINT sbrRatio; /* sbr sampling rate ratio: dual- or single-rate */ UCHAR useTns; /* flag: use temporal noise shaping */ @@ -222,6 +224,36 @@ typedef struct { typedef struct AAC_ENC *HANDLE_AAC_ENC; +/** + * \brief Calculate framesize in bits for given bit rate, frame length and sampling rate. + * + * \param bitRate Ttarget bitrate in bits per second. + * \param frameLength Number of audio samples in one frame. + * \param samplingRate Sampling rate in Hz. + * + * \return Framesize in bits per frame. +*/ +INT FDKaacEnc_CalcBitsPerFrame( + const INT bitRate, + const INT frameLength, + const INT samplingRate + ); + +/** + * \brief Calculate bitrate in bits per second for given framesize, frame length and sampling rate. + * + * \param bitsPerFrame Framesize in bits per frame. + * \param frameLength Number of audio samples in one frame. + * \param samplingRate Sampling rate in Hz. + * + * \return Bitrate in bits per second. +*/ +INT FDKaacEnc_CalcBitrate( + const INT bitsPerFrame, + const INT frameLength, + const INT samplingRate + ); + /** * \brief Limit given bit rate to a valid value * \param hTpEnc transport encoder handle diff --git a/libAACenc/src/aacenc_lib.cpp b/libAACenc/src/aacenc_lib.cpp index 02f83bf..9a3b214 100644 --- a/libAACenc/src/aacenc_lib.cpp +++ b/libAACenc/src/aacenc_lib.cpp @@ -98,7 +98,7 @@ amm-info@iis.fraunhofer.de /* Encoder library info */ #define AACENCODER_LIB_VL0 3 #define AACENCODER_LIB_VL1 4 -#define AACENCODER_LIB_VL2 14 +#define AACENCODER_LIB_VL2 19 #define AACENCODER_LIB_TITLE "AAC Encoder" #ifdef __ANDROID__ #define AACENCODER_LIB_BUILD_DATE "" @@ -153,6 +153,7 @@ typedef struct { UINT userAfterburner; UINT userFramelength; UINT userAncDataRate; + UINT userPeakBitrate; UCHAR userTns; /*!< Use TNS coding. */ UCHAR userPns; /*!< Use PNS coding. */ @@ -326,10 +327,7 @@ static inline INT isSbrActive(const HANDLE_AACENC_CONFIG hAacConfig) { INT sbrUsed = 0; - if ( (hAacConfig->audioObjectType==AOT_SBR) || (hAacConfig->audioObjectType==AOT_PS) - || (hAacConfig->audioObjectType==AOT_MP2_SBR) || (hAacConfig->audioObjectType==AOT_MP2_PS) - || (hAacConfig->audioObjectType==AOT_DABPLUS_SBR) || (hAacConfig->audioObjectType==AOT_DABPLUS_PS) - || (hAacConfig->audioObjectType==AOT_DRM_SBR) || (hAacConfig->audioObjectType==AOT_DRM_MPEG_PS) ) + if ( (hAacConfig->audioObjectType==AOT_SBR) || (hAacConfig->audioObjectType==AOT_PS) ) { sbrUsed = 1; } @@ -345,10 +343,7 @@ static inline INT isPsActive(const AUDIO_OBJECT_TYPE audioObjectType) { INT psUsed = 0; - if ( (audioObjectType==AOT_PS) - || (audioObjectType==AOT_MP2_PS) - || (audioObjectType==AOT_DABPLUS_PS) - || (audioObjectType==AOT_DRM_MPEG_PS) ) + if ( (audioObjectType==AOT_PS) ) { psUsed = 1; } @@ -373,8 +368,7 @@ static SBR_PS_SIGNALING getSbrSignalingMode( sbrSignaling = SIG_IMPLICIT; /* default: implicit signaling */ } - if ((audioObjectType==AOT_AAC_LC) || (audioObjectType==AOT_SBR) || (audioObjectType==AOT_PS) || - (audioObjectType==AOT_MP2_AAC_LC) || (audioObjectType==AOT_MP2_SBR) || (audioObjectType==AOT_MP2_PS) ) { + if ( (audioObjectType==AOT_AAC_LC) || (audioObjectType==AOT_SBR) || (audioObjectType==AOT_PS) ) { switch (transportType) { case TT_MP4_ADIF: case TT_MP4_ADTS: @@ -430,22 +424,7 @@ static void FDKaacEnc_MapConfig( cc->flags = 0; - /* Map virtual aot to transport aot. */ - switch (hAacConfig->audioObjectType) { - case AOT_MP2_AAC_LC: - transport_AOT = AOT_AAC_LC; - break; - case AOT_MP2_SBR: - transport_AOT = AOT_SBR; - cc->flags |= CC_SBR; - break; - case AOT_MP2_PS: - transport_AOT = AOT_PS; - cc->flags |= CC_SBR; - break; - default: - transport_AOT = hAacConfig->audioObjectType; - } + transport_AOT = hAacConfig->audioObjectType; if (hAacConfig->audioObjectType == AOT_ER_AAC_ELD) { cc->flags |= (hAacConfig->syntaxFlags & AC_SBR_PRESENT) ? CC_SBR : 0; @@ -511,16 +490,7 @@ static void FDKaacEnc_MapConfig( cc->samplingRate = hAacConfig->sampleRate; /* Mpeg-4 signaling for transport library. */ - switch ( hAacConfig->audioObjectType ) { - case AOT_MP2_AAC_LC: - case AOT_MP2_SBR: - case AOT_MP2_PS: - cc->flags &= ~CC_MPEG_ID; /* Required for ADTS. */ - cc->extAOT = AOT_NULL_OBJECT; - break; - default: - cc->flags |= CC_MPEG_ID; - } + cc->flags |= CC_MPEG_ID; /* ER-tools signaling. */ cc->flags |= (hAacConfig->syntaxFlags & AC_ER_VCB11) ? CC_VCB11 : 0; @@ -585,6 +555,7 @@ AAC_ENCODER_ERROR aacEncDefaultConfig(HANDLE_AACENC_CONFIG hAacConfig, config->userChannelMode = hAacConfig->channelMode; config->userBitrate = hAacConfig->bitRate; config->userBitrateMode = hAacConfig->bitrateMode; + config->userPeakBitrate = (UINT)-1; config->userBandwidth = hAacConfig->bandWidth; config->userTns = hAacConfig->useTns; config->userPns = hAacConfig->usePns; @@ -792,12 +763,15 @@ AACENC_ERROR FDKaacEnc_AdjustEncSettings(HANDLE_AACENCODER hAacEncoder, hAacConfig->syntaxFlags = 0; hAacConfig->epConfig = -1; + if (config->userTpType==TT_MP4_LATM_MCP1 || config->userTpType==TT_MP4_LATM_MCP0 || config->userTpType==TT_MP4_LOAS) { + hAacConfig->audioMuxVersion = config->userTpAmxv; + } + else { + hAacConfig->audioMuxVersion = -1; + } + /* Adapt internal AOT when necessary. */ switch ( hAacConfig->audioObjectType ) { - case AOT_MP2_AAC_LC: - case AOT_MP2_SBR: - case AOT_MP2_PS: - hAacConfig->usePns = 0; case AOT_AAC_LC: case AOT_SBR: case AOT_PS: @@ -884,6 +858,18 @@ AACENC_ERROR FDKaacEnc_AdjustEncSettings(HANDLE_AACENCODER hAacEncoder, } } + if ((hAacConfig->bitrateMode >= 0) && (hAacConfig->bitrateMode <= 5)) { + if ((INT)config->userPeakBitrate != -1) { + hAacConfig->maxBitsPerFrame = (FDKaacEnc_CalcBitsPerFrame(fMax(hAacConfig->bitRate, (INT)config->userPeakBitrate), hAacConfig->framelength, hAacConfig->sampleRate) + 7)&~7; + } + else { + hAacConfig->maxBitsPerFrame = -1; + } + if (hAacConfig->audioMuxVersion==2) { + hAacConfig->minBitsPerFrame = fMin(32*8, FDKaacEnc_CalcBitsPerFrame(hAacConfig->bitRate, hAacConfig->framelength, hAacConfig->sampleRate))&~7; + } + } + /* Initialize SBR parameters */ if ( (hAacConfig->audioObjectType==AOT_ER_AAC_ELD) && (config->userSbrEnabled == (UCHAR)-1) && (config->userSbrRatio==0) ) @@ -1139,7 +1125,7 @@ static AACENC_ERROR aacEncInit(HANDLE_AACENCODER hAacEncoder, hAacConfig); /* create flags for transport encoder */ - if (config->userTpAmxv == 1) { + if (config->userTpAmxv != 0) { flags |= TP_FLAG_LATM_AMV; } /* Clear output buffer */ @@ -1569,7 +1555,7 @@ AACENC_ERROR aacEncEncode( && ((hAacEncoder->extParam.userChannelMode==MODE_1_2_2)||(hAacEncoder->extParam.userChannelMode==MODE_1_2_2_1)) ) { /* Set matrix mixdown coefficient. */ - UINT pceValue = (UINT)( (1<<3) | ((matrix_mixdown_idx&0x3)<<1) | 1 ); + UINT pceValue = (UINT)( (0<<3) | ((matrix_mixdown_idx&0x3)<<1) | 1 ); if (hAacEncoder->extParam.userPceAdditions != pceValue) { hAacEncoder->extParam.userPceAdditions = pceValue; hAacEncoder->InitFlags |= AACENC_INIT_TRANSPORT; @@ -1785,19 +1771,16 @@ AACENC_ERROR aacEncoder_SetParam( /* check if AOT matches the allocated modules */ switch ( value ) { case AOT_PS: - case AOT_MP2_PS: if (!(hAacEncoder->encoder_modis & (ENC_MODE_FLAG_PS))) { err = AACENC_INVALID_CONFIG; goto bail; } case AOT_SBR: - case AOT_MP2_SBR: if (!(hAacEncoder->encoder_modis & (ENC_MODE_FLAG_SBR))) { err = AACENC_INVALID_CONFIG; goto bail; } case AOT_AAC_LC: - case AOT_MP2_AAC_LC: case AOT_ER_AAC_LD: case AOT_ER_AAC_ELD: if (!(hAacEncoder->encoder_modis & (ENC_MODE_FLAG_AAC))) { @@ -1823,6 +1806,7 @@ AACENC_ERROR aacEncoder_SetParam( if (settings->userBitrateMode != value) { switch ( value ) { case 0: + case 1: case 2: case 3: case 4: case 5: case 8: settings->userBitrateMode = value; hAacEncoder->InitFlags |= AACENC_INIT_CONFIG | AACENC_INIT_TRANSPORT; @@ -1973,6 +1957,16 @@ AACENC_ERROR aacEncoder_SetParam( hAacEncoder->InitFlags |= AACENC_INIT_TRANSPORT; } break; + case AACENC_AUDIOMUXVER: + if (settings->userTpAmxv != value) { + if ( !((value==0) || (value==1) || (value==2)) ) { + err = AACENC_INVALID_CONFIG; + break; + } + settings->userTpAmxv = value; + hAacEncoder->InitFlags |= AACENC_INIT_TRANSPORT; + } + break; case AACENC_TPSUBFRAMES: if (settings->userTpNsubFrames != value) { if (! ( (value>=1) && (value<=4) ) ) { @@ -2006,6 +2000,12 @@ AACENC_ERROR aacEncoder_SetParam( hAacEncoder->InitFlags |= AACENC_INIT_CONFIG; } break; + case AACENC_PEAK_BITRATE: + if (settings->userPeakBitrate != value) { + settings->userPeakBitrate = value; + hAacEncoder->InitFlags |= AACENC_INIT_CONFIG | AACENC_INIT_TRANSPORT; + } + break; default: err = AACENC_UNSUPPORTED_PARAMETER; break; @@ -2076,6 +2076,9 @@ UINT aacEncoder_GetParam( case AACENC_HEADER_PERIOD: value = (UINT)hAacEncoder->coderConfig.headerPeriod; break; + case AACENC_AUDIOMUXVER: + value = (UINT)hAacEncoder->aacConfig.audioMuxVersion; + break; case AACENC_TPSUBFRAMES: value = (UINT)settings->userTpNsubFrames; break; @@ -2088,6 +2091,12 @@ UINT aacEncoder_GetParam( case AACENC_METADATA_MODE: value = (hAacEncoder->metaDataAllowed==0) ? 0 : (UINT)settings->userMetaDataMode; break; + case AACENC_PEAK_BITRATE: + value = (UINT)-1; /* peak bitrate parameter is meaningless */ + if ( ((INT)hAacEncoder->extParam.userPeakBitrate!=-1) ) { + value = (UINT)(fMax((INT)hAacEncoder->extParam.userPeakBitrate, hAacEncoder->aacConfig.bitRate)); /* peak bitrate parameter is in use */ + } + break; default: //err = MPS_INVALID_PARAMETER; break; diff --git a/libAACenc/src/adj_thr.cpp b/libAACenc/src/adj_thr.cpp index 69a70b4..c318843 100644 --- a/libAACenc/src/adj_thr.cpp +++ b/libAACenc/src/adj_thr.cpp @@ -2138,7 +2138,7 @@ static FIXP_DBL FDKaacEnc_bitresCalcBitFac(const INT bitresBits, bresParam->clipSpendLow, bresParam->clipSpendHigh, bresParam->minBitSpend, bresParam->maxBitSpend, bitspend_slope); - pe_pers = fDivNorm(pex - adjThrChan->peMin, adjThrChan->peMax - adjThrChan->peMin); + pe_pers = (pex > adjThrChan->peMin) ? fDivNorm(pex - adjThrChan->peMin, adjThrChan->peMax - adjThrChan->peMin) : 0; tmp_fix = fMult(((FIXP_DBL)bitSpend + (FIXP_DBL)bitSave), pe_pers); bitresFac_fix = (UNITY>>1) - ((FIXP_DBL)bitSave>>1) + (tmp_fix>>1); qbres = (DFRACT_BITS-2); diff --git a/libAACenc/src/intensity.cpp b/libAACenc/src/intensity.cpp index 6d807f7..b45b27b 100644 --- a/libAACenc/src/intensity.cpp +++ b/libAACenc/src/intensity.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 @@ -325,7 +325,6 @@ FDKaacEnc_prepareIntensityDecision(const FIXP_DBL *sfbEnergyLeft, channelCorr[sfb + sfboffs] = FL2FXCONST_DBL(0.0f); - FDK_ASSERT(50 >= 49); /* max width of scalefactorband is 96; width's are always even */ /* inv_n is scaled with factor 2 to compensate fMultDiv2() in subsequent loops */ inv_n = GetInvInt((sfbOffset[sfb + sfboffs + 1] - sfbOffset[sfb + sfboffs])>>1); diff --git a/libAACenc/src/psy_configuration.cpp b/libAACenc/src/psy_configuration.cpp index 4393fa1..9a72c68 100644 --- a/libAACenc/src/psy_configuration.cpp +++ b/libAACenc/src/psy_configuration.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 @@ -634,13 +634,14 @@ AAC_ENCODER_ERROR FDKaacEnc_InitPsyConfiguration(INT bitrate, if (psyConf->sfbOffset[sfb] >= psyConf->lowpassLine) break; } - psyConf->sfbActive = sfb; + psyConf->sfbActive = FDKmax(sfb, 1); for (sfb = 0; sfb < psyConf->sfbCnt; sfb++){ if (psyConf->sfbOffset[sfb] >= psyConf->lowpassLineLFE) break; } psyConf->sfbActiveLFE = sfb; + psyConf->sfbActive = FDKmax(psyConf->sfbActive, psyConf->sfbActiveLFE); /* calculate minSnr */ FDKaacEnc_initMinSnr(bitrate, diff --git a/libAACenc/src/psy_main.cpp b/libAACenc/src/psy_main.cpp index 1c593f8..3cc9438 100644 --- a/libAACenc/src/psy_main.cpp +++ b/libAACenc/src/psy_main.cpp @@ -621,7 +621,7 @@ AAC_ENCODER_ERROR FDKaacEnc_psyMain(INT channels, FDKmemclear(&psyData[ch]->mdctSpectrum[psyData[ch]->lowpassLine+wOffset], (windowLength[ch]-psyData[ch]->lowpassLine)*sizeof(FIXP_DBL)); - if (hPsyConfLong->filterbank != FB_LC) { + if ( (hPsyConfLong->filterbank != FB_LC) && (psyData[ch]->lowpassLine >= FADE_OUT_LEN) ) { /* Do blending to reduce gibbs artifacts */ for (int i=0; imdctSpectrum[psyData[ch]->lowpassLine+wOffset - FADE_OUT_LEN + i] = fMult(psyData[ch]->mdctSpectrum[psyData[ch]->lowpassLine+wOffset - FADE_OUT_LEN + i], fadeOutFactor[i]); diff --git a/libAACenc/src/qc_main.cpp b/libAACenc/src/qc_main.cpp index 278bcb2..7503309 100644 --- a/libAACenc/src/qc_main.cpp +++ b/libAACenc/src/qc_main.cpp @@ -1248,6 +1248,8 @@ AAC_ENCODER_ERROR FDKaacEnc_updateFillBits(CHANNEL_MAPPING* cm, case QCDATA_BR_MODE_VBR_4: case QCDATA_BR_MODE_VBR_5: qcOut[0]->totFillBits = (qcOut[0]->grantedDynBits - qcOut[0]->usedDynBits)&7; /* precalculate alignment bits */ + qcOut[0]->totalBits = qcOut[0]->staticBits + qcOut[0]->usedDynBits + qcOut[0]->totFillBits + qcOut[0]->elementExtBits + qcOut[0]->globalExtBits; + qcOut[0]->totFillBits += ( fixMax(0, qcKernel->minBitsPerFrame - qcOut[0]->totalBits) + 7) & ~7; break; case QCDATA_BR_MODE_CBR: @@ -1257,6 +1259,8 @@ AAC_ENCODER_ERROR FDKaacEnc_updateFillBits(CHANNEL_MAPPING* cm, /* processing fill-bits */ INT deltaBitRes = qcOut[0]->grantedDynBits - qcOut[0]->usedDynBits ; qcOut[0]->totFillBits = fixMax((deltaBitRes&7), (deltaBitRes - (fixMax(0,bitResSpace-7)&~7))); + qcOut[0]->totalBits = qcOut[0]->staticBits + qcOut[0]->usedDynBits + qcOut[0]->totFillBits + qcOut[0]->elementExtBits + qcOut[0]->globalExtBits; + qcOut[0]->totFillBits += ( fixMax(0, qcKernel->minBitsPerFrame - qcOut[0]->totalBits) + 7) & ~7; break; } /* switch (qcKernel->bitrateMode) */ diff --git a/libFDK/include/fixpoint_math.h b/libFDK/include/fixpoint_math.h index df141d3..88e2f09 100644 --- a/libFDK/include/fixpoint_math.h +++ b/libFDK/include/fixpoint_math.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 @@ -438,11 +438,11 @@ inline FIXP_DBL fAddSaturate(const FIXP_DBL a, const FIXP_DBL b) /***************************************************************************** - array for 1/n, n=1..50 + array for 1/n, n=1..80 ****************************************************************************/ - extern const FIXP_DBL invCount[50]; + extern const FIXP_DBL invCount[80]; LNK_SECTION_INITCODE inline void InitInvInt(void) {} @@ -450,14 +450,14 @@ inline FIXP_DBL fAddSaturate(const FIXP_DBL a, const FIXP_DBL b) /** * \brief Calculate the value of 1/i where i is a integer value. It supports - * input values from 1 upto 50. + * input values from 1 upto 80. * \param intValue Integer input value. * \param FIXP_DBL representation of 1/intValue */ inline FIXP_DBL GetInvInt(int intValue) { - FDK_ASSERT((intValue > 0) && (intValue < 50)); - FDK_ASSERT(intValue<50); + FDK_ASSERT((intValue > 0) && (intValue < 80)); + FDK_ASSERT(intValue<80); return invCount[intValue]; } diff --git a/libFDK/src/FDK_core.cpp b/libFDK/src/FDK_core.cpp index cccb925..8fa5596 100644 --- a/libFDK/src/FDK_core.cpp +++ b/libFDK/src/FDK_core.cpp @@ -93,7 +93,7 @@ amm-info@iis.fraunhofer.de /* FDK tools library info */ #define FDK_TOOLS_LIB_VL0 2 #define FDK_TOOLS_LIB_VL1 3 -#define FDK_TOOLS_LIB_VL2 3 +#define FDK_TOOLS_LIB_VL2 4 #define FDK_TOOLS_LIB_TITLE "FDK Tools" #ifdef __ANDROID__ #define FDK_TOOLS_LIB_BUILD_DATE "" diff --git a/libFDK/src/FDK_tools_rom.cpp b/libFDK/src/FDK_tools_rom.cpp index c6e517e..49f0ee1 100644 --- a/libFDK/src/FDK_tools_rom.cpp +++ b/libFDK/src/FDK_tools_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 @@ -1902,7 +1902,7 @@ const USHORT sqrt_tab[49]={ 0xb504}; LNK_SECTION_CONSTDATA_L1 -const FIXP_DBL invCount[50]= /* This could be 16-bit wide */ +const FIXP_DBL invCount[80]= /* This could be 16-bit wide */ { 0x00000000, 0x7fffffff, 0x40000000, 0x2aaaaaab, 0x20000000, 0x1999999a, 0x15555555, 0x12492492, 0x10000000, 0x0e38e38e, @@ -1913,7 +1913,13 @@ const FIXP_DBL invCount[50]= /* This could be 16-bit wide */ 0x04444444, 0x04210842, 0x04000000, 0x03e0f83e, 0x03c3c3c4, 0x03a83a84, 0x038e38e4, 0x03759f23, 0x035e50d8, 0x03483483, 0x03333333, 0x031f3832, 0x030c30c3, 0x02fa0be8, 0x02e8ba2f, - 0x02d82d83, 0x02c8590b, 0x02b93105, 0x02aaaaab, 0x029cbc15 + 0x02d82d83, 0x02c8590b, 0x02b93105, 0x02aaaaab, 0x029cbc15, + 0x028f5c29, 0x02828283, 0x02762762, 0x026a439f, 0x025ed098, + 0x0253c825, 0x02492492, 0x023ee090, 0x0234f72c, 0x022b63cc, + 0x02222222, 0x02192e2a, 0x02108421, 0x02082082, 0x02000000, + 0x01f81f82, 0x01f07c1f, 0x01e9131b, 0x01e1e1e2, 0x01dae607, + 0x01d41d42, 0x01cd8569, 0x01c71c72, 0x01c0e070, 0x01bacf91, + 0x01b4e81b, 0x01af286c, 0x01a98ef6, 0x01a41a42, 0x019ec8e9 }; @@ -2033,19 +2039,6 @@ static const element_list_t node_aac_cpe = { { &node_aac_cpe0, &node_aac_cpe1 } }; -#define el_mpegsres_sce &el_aac_sce[2] - -static const element_list_t node_mpegsres_sce = { - el_mpegsres_sce, - { NULL, NULL } -}; - -static const element_list_t node_mpegsres_cpe = { - el_aac_cpe1, - { NULL, NULL } -}; - - /* * AOT C- {17,23} * epConfig = 0,1 @@ -2424,13 +2417,6 @@ const element_list_t * getBitstreamElementList(AUDIO_OBJECT_TYPE aot, SCHAR epCo else return &node_eld_cpe_epc1; } - case AOT_MPEGS_RESIDUALS: - if (nChannels == 1) { - return &node_mpegsres_sce; - } else { - return &node_mpegsres_cpe; - } - break; default: break; } diff --git a/libMpegTPDec/src/tpdec_lib.cpp b/libMpegTPDec/src/tpdec_lib.cpp index 445615d..950af64 100644 --- a/libMpegTPDec/src/tpdec_lib.cpp +++ b/libMpegTPDec/src/tpdec_lib.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 @@ -1100,7 +1100,6 @@ TRANSPORTDEC_ERROR transportDec_ReadAccessUnit( const HANDLE_TRANSPORTDEC hTp, c } break; - case TT_RSVD50: case TT_MP4_ADTS: case TT_MP4_LOAS: err = transportDec_readStream(hTp, layer); diff --git a/libMpegTPDec/src/version b/libMpegTPDec/src/version index fc7e5f0..18fc9ba 100644 --- a/libMpegTPDec/src/version +++ b/libMpegTPDec/src/version @@ -2,7 +2,7 @@ /* library info */ #define TP_LIB_VL0 2 #define TP_LIB_VL1 3 -#define TP_LIB_VL2 4 +#define TP_LIB_VL2 5 #define TP_LIB_TITLE "MPEG Transport" #ifdef __ANDROID__ #define TP_LIB_BUILD_DATE "" diff --git a/libMpegTPEnc/src/tpenc_latm.cpp b/libMpegTPEnc/src/tpenc_latm.cpp index 58e51ef..f292019 100644 --- a/libMpegTPEnc/src/tpenc_latm.cpp +++ b/libMpegTPEnc/src/tpenc_latm.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 @@ -296,6 +296,7 @@ CreateStreamMuxConfig( USHORT coreFrameOffset=0; + hAss->taraBufferFullness = 0xFF; hAss->audioMuxVersionA = 0; /* for future extensions */ hAss->streamMuxConfigBits = 0; @@ -339,13 +340,7 @@ CreateStreamMuxConfig( hAss->streamMuxConfigBits+=1; } if( (useSameConfig == 0) || (transLayer==0) ) { - UINT bits; - - if ( hAss->audioMuxVersion == 1 ) { - FDKpushFor(hBs, 2); /* align to ASC, even if we do not know the length of the "ascLen" field yet */ - } - - bits = FDKgetValidBits( hBs ); + const UINT alignAnchor = FDKgetValidBits(hBs); transportEnc_writeASC( hBs, @@ -353,19 +348,24 @@ CreateStreamMuxConfig( cb ); - bits = FDKgetValidBits( hBs ) - bits; - if ( hAss->audioMuxVersion == 1 ) { - FDKpushBack(hBs, bits+2); - hAss->streamMuxConfigBits += transportEnc_LatmWriteValue( hBs, bits ); + UINT ascLen = transportEnc_LatmWriteValue(hBs, 0); + FDKbyteAlign(hBs, alignAnchor); + ascLen = FDKgetValidBits(hBs) - alignAnchor - ascLen; + FDKpushBack(hBs, FDKgetValidBits(hBs) - alignAnchor); + + transportEnc_LatmWriteValue(hBs, ascLen); + transportEnc_writeASC( hBs, hAss->config[prog][layer], cb ); + + FDKbyteAlign(hBs, alignAnchor); /* asc length fillbits */ } - hAss->streamMuxConfigBits += bits; /* add asc length to smc summary */ + hAss->streamMuxConfigBits += FDKgetValidBits(hBs) - alignAnchor; /* add asc length to smc summary */ } transLayer++; @@ -384,7 +384,6 @@ CreateStreamMuxConfig( case AOT_ER_AAC_LD : case AOT_ER_AAC_ELD : case AOT_USAC: - case AOT_RSVD50: p_linfo->frameLengthType = 0; FDKwriteBits( hBs, p_linfo->frameLengthType, 3 ); /* frameLengthType */ diff --git a/libMpegTPEnc/src/version b/libMpegTPEnc/src/version index fc7e5f0..8742568 100644 --- a/libMpegTPEnc/src/version +++ b/libMpegTPEnc/src/version @@ -2,7 +2,7 @@ /* library info */ #define TP_LIB_VL0 2 #define TP_LIB_VL1 3 -#define TP_LIB_VL2 4 +#define TP_LIB_VL2 6 #define TP_LIB_TITLE "MPEG Transport" #ifdef __ANDROID__ #define TP_LIB_BUILD_DATE "" diff --git a/libSBRdec/src/sbrdecoder.cpp b/libSBRdec/src/sbrdecoder.cpp index 619e4fd..e15145a 100644 --- a/libSBRdec/src/sbrdecoder.cpp +++ b/libSBRdec/src/sbrdecoder.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 @@ -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 6 +#define SBRDECODER_LIB_VL2 7 #define SBRDECODER_LIB_TITLE "SBR Decoder" #ifdef __ANDROID__ #define SBRDECODER_LIB_BUILD_DATE "" @@ -318,7 +318,6 @@ SBR_ERROR sbrDecoder_ResetElement ( case AOT_PS: case AOT_ER_AAC_SCAL: case AOT_DRM_AAC: - case AOT_DRM_SURROUND: if (CreatePsDec ( &self->hParametricStereoDec, samplesPerFrame )) { sbrError = SBRDEC_CREATE_ERROR; goto bail; @@ -503,7 +502,6 @@ SBR_ERROR sbrDecoder_InitElement ( case AOT_PS: case AOT_ER_AAC_SCAL: case AOT_DRM_AAC: - case AOT_DRM_SURROUND: elChannels = 2; break; default: diff --git a/libSBRenc/src/nf_est.cpp b/libSBRenc/src/nf_est.cpp index 7a3c022..385a043 100644 --- a/libSBRenc/src/nf_est.cpp +++ b/libSBRenc/src/nf_est.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 @@ -268,8 +268,9 @@ qmfBasedNoiseFloorDetection(FIXP_DBL *noiseLevel, /*!< Pointer to v /* * Add a noise floor offset to compensate for bias in the detector *****************************************************************/ - if(!missingHarmonicFlag) - *noiseLevel = fMult(*noiseLevel, noiseFloorOffset)<<(NOISE_FLOOR_OFFSET_SCALING); + if(!missingHarmonicFlag) { + *noiseLevel = fixMin(fMult(*noiseLevel, noiseFloorOffset), (FIXP_DBL)MAXVAL_DBL>>NOISE_FLOOR_OFFSET_SCALING) << NOISE_FLOOR_OFFSET_SCALING; + } /* * check to see that we don't exceed the maximum allowed level diff --git a/libSBRenc/src/sbr_encoder.cpp b/libSBRenc/src/sbr_encoder.cpp index 221aecd..9bb98c8 100644 --- a/libSBRenc/src/sbr_encoder.cpp +++ b/libSBRenc/src/sbr_encoder.cpp @@ -103,7 +103,7 @@ amm-info@iis.fraunhofer.de #define SBRENCODER_LIB_VL0 3 #define SBRENCODER_LIB_VL1 3 -#define SBRENCODER_LIB_VL2 6 +#define SBRENCODER_LIB_VL2 8 @@ -1552,12 +1552,6 @@ INT FDKsbrEnc_EnvInit ( hSbrElement->sbrConfigData.sbrSyntaxFlags = 0; switch (aot) { - case AOT_DRM_MPEG_PS: - case AOT_DRM_SBR: - hSbrElement->sbrConfigData.sbrSyntaxFlags |= SBR_SYNTAX_SCALABLE; - hSbrElement->sbrConfigData.sbrSyntaxFlags |= SBR_SYNTAX_DRM_CRC; - hSbrElement->sbrConfigData.sbrSyntaxFlags |= SBR_SYNTAX_CRC; - break; case AOT_ER_AAC_ELD: hSbrElement->sbrConfigData.sbrSyntaxFlags |= SBR_SYNTAX_LOW_DELAY; break; @@ -1847,7 +1841,7 @@ INT sbrEncoder_Init( - if ( (aot==AOT_PS) || (aot==AOT_MP2_PS) || (aot==AOT_DABPLUS_PS) || (aot==AOT_DRM_MPEG_PS) ) { + if ( (aot==AOT_PS) ) { usePs = 1; } if ( (aot==AOT_ER_AAC_ELD) ) { diff --git a/libSBRenc/src/tran_det.cpp b/libSBRenc/src/tran_det.cpp index 1e0a59f..6c62b4c 100644 --- a/libSBRenc/src/tran_det.cpp +++ b/libSBRenc/src/tran_det.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 @@ -676,7 +676,7 @@ FDKsbrEnc_InitSbrTransientDetector(HANDLE_SBR_TRANSIENT_DETECTOR h_sbrTransientD tmp = fixMax(tmp, FL2FXCONST_DBL(0.0001)); tmp = fDivNorm(FL2FXCONST_DBL(0.000075), fPow2(tmp), &scale_1); - scale_1 = -(scale_1 + scale_0 + 2); + scale_1 = (scale_1 + scale_0 + 2); FDK_ASSERT(no_cols <= QMF_MAX_TIME_SLOTS); FDK_ASSERT(no_rows <= QMF_CHANNELS); @@ -684,14 +684,7 @@ FDKsbrEnc_InitSbrTransientDetector(HANDLE_SBR_TRANSIENT_DETECTOR h_sbrTransientD h_sbrTransientDetector->no_cols = no_cols; h_sbrTransientDetector->tran_thr = (FIXP_DBL)((params->tran_thr << (32-24-1)) / no_rows); h_sbrTransientDetector->tran_fc = tran_fc; - - if (scale_1>=0) { - h_sbrTransientDetector->split_thr = fMult(tmp, bitrateFactor_fix) >> scale_1; - } - else { - h_sbrTransientDetector->split_thr = fMult(tmp, bitrateFactor_fix) << (-scale_1); - } - + h_sbrTransientDetector->split_thr = scaleValueSaturate(fMult(tmp, bitrateFactor_fix), scale_1); h_sbrTransientDetector->no_rows = no_rows; h_sbrTransientDetector->mode = params->tran_det_mode; h_sbrTransientDetector->prevLowBandEnergy = FL2FXCONST_DBL(0.0f); diff --git a/libSYS/include/FDK_audio.h b/libSYS/include/FDK_audio.h index 0660f4c..98ded3b 100644 --- a/libSYS/include/FDK_audio.h +++ b/libSYS/include/FDK_audio.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 @@ -134,13 +134,7 @@ typedef enum TT_MP4_LOAS = 10, /**< Audio Sync Stream. */ - TT_DRM = 12, /**< Digital Radio Mondial (DRM30/DRM+) bitstream format. */ - - TT_MP1_L1 = 16, /**< MPEG 1 Audio Layer 1 audio bitstream. */ - TT_MP1_L2 = 17, /**< MPEG 1 Audio Layer 2 audio bitstream. */ - TT_MP1_L3 = 18, /**< MPEG 1 Audio Layer 3 audio bitstream. */ - - TT_RSVD50 = 50 /**< */ + TT_DRM = 12 /**< Digital Radio Mondial (DRM30/DRM+) bitstream format. */ } TRANSPORT_TYPE; @@ -203,38 +197,22 @@ typedef enum AOT_SAOC = 43, /**< SAOC */ AOT_LD_MPEGS = 44, /**< Low Delay MPEG Surround */ - AOT_RSVD50 = 50, /**< Interim AOT for Rsvd50 */ - /* Pseudo AOTs */ - AOT_MP2_AAC_MAIN = 128, /**< Virtual AOT MP2 Main profile */ - AOT_MP2_AAC_LC = 129, /**< Virtual AOT MP2 Low Complexity profile */ - AOT_MP2_AAC_SSR = 130, /**< Virtual AOT MP2 Scalable Sampling Rate profile */ - - AOT_MP2_SBR = 132, /**< Virtual AOT MP2 Low Complexity Profile with SBR */ - - AOT_DAB = 134, /**< Virtual AOT for DAB (Layer2 with scalefactor CRC) */ - AOT_DABPLUS_AAC_LC = 135, /**< Virtual AOT for DAB plus AAC-LC */ - AOT_DABPLUS_SBR = 136, /**< Virtual AOT for DAB plus HE-AAC */ - AOT_DABPLUS_PS = 137, /**< Virtual AOT for DAB plus HE-AAC v2 */ - - AOT_PLAIN_MP1 = 140, /**< Virtual AOT for plain mp1 */ - AOT_PLAIN_MP2 = 141, /**< Virtual AOT for plain mp2 */ - AOT_PLAIN_MP3 = 142, /**< Virtual AOT for plain mp3 */ - AOT_DRM_AAC = 143, /**< Virtual AOT for DRM (ER-AAC-SCAL without SBR) */ AOT_DRM_SBR = 144, /**< Virtual AOT for DRM (ER-AAC-SCAL with SBR) */ - AOT_DRM_MPEG_PS = 145, /**< Virtual AOT for DRM (ER-AAC-SCAL with SBR and MPEG-PS) */ - AOT_DRM_SURROUND = 146, /**< Virtual AOT for DRM Surround (ER-AAC-SCAL (+SBR) +MPS) */ - - AOT_MP2_PS = 156, /**< Virtual AOT MP2 Low Complexity Profile with SBR and PS */ - - AOT_MPEGS_RESIDUALS = 256 /**< Virtual AOT for MPEG Surround residuals */ + AOT_DRM_MPEG_PS = 145 /**< Virtual AOT for DRM (ER-AAC-SCAL with SBR and MPEG-PS) */ } AUDIO_OBJECT_TYPE; +#define CAN_DO_PS(aot) \ + ((aot) == AOT_AAC_LC \ +|| (aot) == AOT_SBR \ +|| (aot) == AOT_PS \ +|| (aot) == AOT_ER_BSAC \ +|| (aot) == AOT_DRM_AAC) + #define IS_USAC(aot) \ - ((aot) == AOT_USAC \ -|| (aot) == AOT_RSVD50) + ((aot) == AOT_USAC) #define IS_LOWDELAY(aot) \ ((aot) == AOT_ER_AAC_LD \ diff --git a/libSYS/src/genericStds.cpp b/libSYS/src/genericStds.cpp index 47d62fc..53abe06 100644 --- a/libSYS/src/genericStds.cpp +++ b/libSYS/src/genericStds.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 @@ -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 6 +#define SYS_LIB_VL2 7 #define SYS_LIB_TITLE "System Integration Library" #ifdef __ANDROID__ #define SYS_LIB_BUILD_DATE "" -- cgit v1.2.3 From 4834f01bdf9b9f371fcbb0b9cf4f7297fdf1fd55 Mon Sep 17 00:00:00 2001 From: Jean-Michel Trivi Date: Tue, 5 Apr 2016 12:38:32 -0700 Subject: Fix aacDecoder_drcExtractAndMap() Parse DVB DRC data only when numThreads is below MAX_DRC_THREADS. The post-increment is necessary as it is used in fill element DRC data section. This solution parses as many DRC payloads as allowed by MAX_DRC_THREADS and skips all remaining DRC elements in the stream. Bug 27792766 Bug 26751339 Change-Id: Ie1641888bac1757c4d1491119f977fc5d436eaea --- libAACdec/src/aacdec_drc.cpp | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) (limited to 'libAACdec') diff --git a/libAACdec/src/aacdec_drc.cpp b/libAACdec/src/aacdec_drc.cpp index 9cfc5d5..eb8e410 100644 --- a/libAACdec/src/aacdec_drc.cpp +++ b/libAACdec/src/aacdec_drc.cpp @@ -705,11 +705,7 @@ static int aacDecoder_drcExtractAndMap ( } self->numPayloads = 0; - if (self->numThreads >= MAX_DRC_THREADS) { - self->numThreads = MAX_DRC_THREADS - 1; - } - - if (self->dvbAncDataAvailable) + if (self->dvbAncDataAvailable && self->numThreads < MAX_DRC_THREADS) { /* Append a DVB heavy compression payload thread if available. */ int bitsParsed; @@ -735,10 +731,6 @@ static int aacDecoder_drcExtractAndMap ( /* coupling channels not supported */ - if (self->numThreads >= MAX_DRC_THREADS) { - self->numThreads = MAX_DRC_THREADS - 1; - } - /* check for valid threads */ for (thread = 0; thread < self->numThreads; thread++) { CDrcPayload *pThreadBs = &threadBs[thread]; -- cgit v1.2.3 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 --- documentation/aacDecoder.pdf | Bin 505567 -> 387906 bytes 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 +- libFDK/src/FDK_core.cpp | 2 +- libFDK/src/FDK_tools_rom.cpp | 198 ++++++++++++++++++++++++++++++++++- libMpegTPDec/src/tpdec_asc.cpp | 135 +++++++++++++++++++++++- libMpegTPDec/src/tpdec_drm.cpp | 146 ++++++++++++++++++++++++++ libMpegTPDec/src/tpdec_drm.h | 194 +++++++++++++++++++++++++++++++++++ libMpegTPDec/src/tpdec_lib.cpp | 27 +++++ libMpegTPDec/src/version | 2 +- libSBRdec/include/sbrdecoder.h | 3 +- libSBRdec/src/env_calc.cpp | 204 ++++++++++++++++++++++++++----------- libSBRdec/src/env_dec.cpp | 4 +- libSBRdec/src/env_extr.cpp | 4 +- libSBRdec/src/env_extr.h | 12 ++- libSBRdec/src/sbr_dec.cpp | 62 +++++++++-- libSBRdec/src/sbr_dec.h | 8 +- libSBRdec/src/sbr_ram.h | 3 +- libSBRdec/src/sbr_rom.cpp | 11 +- libSBRdec/src/sbr_rom.h | 3 +- libSBRdec/src/sbrdecoder.cpp | 177 ++++++++++++++++++++++++++++---- libSYS/src/genericStds.cpp | 6 +- 26 files changed, 1237 insertions(+), 142 deletions(-) create mode 100644 libMpegTPDec/src/tpdec_drm.cpp create mode 100644 libMpegTPDec/src/tpdec_drm.h (limited to 'libAACdec') diff --git a/documentation/aacDecoder.pdf b/documentation/aacDecoder.pdf index d388576..458fda1 100644 Binary files a/documentation/aacDecoder.pdf and b/documentation/aacDecoder.pdf differ 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) ) { diff --git a/libFDK/src/FDK_core.cpp b/libFDK/src/FDK_core.cpp index f4b510d..1d8ac7b 100644 --- a/libFDK/src/FDK_core.cpp +++ b/libFDK/src/FDK_core.cpp @@ -93,7 +93,7 @@ amm-info@iis.fraunhofer.de /* FDK tools library info */ #define FDK_TOOLS_LIB_VL0 2 #define FDK_TOOLS_LIB_VL1 3 -#define FDK_TOOLS_LIB_VL2 5 +#define FDK_TOOLS_LIB_VL2 6 #define FDK_TOOLS_LIB_TITLE "FDK Tools" #ifdef __ANDROID__ #define FDK_TOOLS_LIB_BUILD_DATE "" diff --git a/libFDK/src/FDK_tools_rom.cpp b/libFDK/src/FDK_tools_rom.cpp index 49f0ee1..29e37f2 100644 --- a/libFDK/src/FDK_tools_rom.cpp +++ b/libFDK/src/FDK_tools_rom.cpp @@ -2236,7 +2236,7 @@ static const rbd_id_t el_aac_cpe1_epc1[] = { ics_info, ms, ltp_data_present, - ltp_data, + /* ltp_data, */ global_gain, section_data, scale_factor_data, @@ -2247,7 +2247,7 @@ static const rbd_id_t el_aac_cpe1_epc1[] = { next_channel, ltp_data_present, - ltp_data, + /* ltp_data, */ global_gain, section_data, scale_factor_data, @@ -2290,7 +2290,178 @@ static const element_list_t node_aac_cpe_epc1 = { { &node_aac_cpe0_epc1, &node_aac_cpe1_epc1 } }; +/* + * AOT = 20 + * epConfig = 0 + */ +static const rbd_id_t el_scal_sce_epc0[] = { + ics_info, /* ESC 1 */ + tns_data_present, + ltp_data_present, + /* ltp_data, */ + global_gain, + section_data, + scale_factor_data, + esc1_hcr, + esc2_rvlc, /* ESC 2 */ + tns_data, /* ESC 3 */ + spectral_data, /* ESC 4 */ + end_of_sequence +}; + +static const struct element_list node_scal_sce_epc0 = { + el_scal_sce_epc0, + { NULL, NULL } +}; + +static const rbd_id_t el_scal_cpe_epc0[] = { + ics_info, /* ESC 0 */ + ms, + tns_data_present, /* ESC 1 (ch 0) */ + ltp_data_present, + /* ltp_data, */ + global_gain, + section_data, + scale_factor_data, + esc1_hcr, + esc2_rvlc, /* ESC 2 (ch 0) */ + tns_data, /* ESC 3 (ch 0) */ + spectral_data, /* ESC 4 (ch 0) */ + next_channel, + tns_data_present, /* ESC 1 (ch 1) */ + ltp_data_present, + global_gain, + section_data, + scale_factor_data, + esc1_hcr, + esc2_rvlc, /* ESC 2 (ch 1) */ + tns_data, /* ESC 3 (ch 1) */ + spectral_data, /* ESC 4 (ch 1) */ + end_of_sequence +}; +static const struct element_list node_scal_cpe_epc0 = { + el_scal_cpe_epc0, + { NULL, NULL } +}; + +/* + * AOT = 20 + * epConfig = 1 + */ +static const rbd_id_t el_scal_sce_epc1[] = { + ics_info, + tns_data_present, + ltp_data_present, + /* ltp_data, */ + global_gain, + section_data, + scale_factor_data, + esc1_hcr, + tns_data, + spectral_data, + end_of_sequence +}; + +static const struct element_list node_scal_sce_epc1 = { + el_scal_sce_epc1, + { NULL, NULL } +}; + +static const rbd_id_t el_scal_cpe_epc1[] = { + ics_info, + ms, + tns_data_present, + ltp_data_present, + /* ltp_data, */ + global_gain, + section_data, + scale_factor_data, + esc1_hcr, + next_channel, + tns_data_present, + ltp_data_present, + /* ltp_data, */ + global_gain, + section_data, + scale_factor_data, + esc1_hcr, + next_channel, + tns_data, + next_channel, + tns_data, + next_channel, + spectral_data, + next_channel, + spectral_data, + end_of_sequence +}; + +static const struct element_list node_scal_cpe_epc1 = { + el_scal_cpe_epc1, + { NULL, NULL } +}; + +/* + * Pseudo AOT for DRM/DRM+ (similar to AOT 20) + * Derived from epConfig = 1 + */ +static const rbd_id_t el_drm_sce[] = { + drmcrc_start_reg, + ics_info, + tns_data_present, + ltp_data_present, + /* ltp_data, */ + global_gain, + section_data, + scale_factor_data, + esc1_hcr, + tns_data, + drmcrc_end_reg, + spectral_data, + end_of_sequence +}; + +static const struct element_list node_drm_sce = { + el_drm_sce, + { NULL, NULL } +}; + +static const rbd_id_t el_drm_cpe[] = { + drmcrc_start_reg, + ics_info, + ms, + tns_data_present, + ltp_data_present, + /* ltp_data, */ + global_gain, + section_data, + scale_factor_data, + esc1_hcr, + next_channel, + tns_data_present, + ltp_data_present, + /* ltp_data, */ + global_gain, + section_data, + scale_factor_data, + esc1_hcr, + next_channel, + tns_data, + next_channel, + tns_data, + drmcrc_end_reg, + next_channel, + spectral_data, + next_channel, + spectral_data, + end_of_sequence +}; + +static const struct element_list node_drm_cpe = { + el_drm_cpe, + { NULL, NULL } +}; /* * AOT = 39 @@ -2405,6 +2576,19 @@ const element_list_t * getBitstreamElementList(AUDIO_OBJECT_TYPE aot, SCHAR epCo return &node_aac_cpe_epc1; } break; + case AOT_ER_AAC_SCAL: + if (nChannels == 1) { + if (epConfig <= 0) + return &node_scal_sce_epc0; + else + return &node_scal_sce_epc1; + } else { + if (epConfig <= 0) + return &node_scal_cpe_epc0; + else + return &node_scal_cpe_epc1; + } + break; case AOT_ER_AAC_ELD: if (nChannels == 1) { if (epConfig <= 0) @@ -2417,6 +2601,16 @@ const element_list_t * getBitstreamElementList(AUDIO_OBJECT_TYPE aot, SCHAR epCo else return &node_eld_cpe_epc1; } + case AOT_DRM_AAC: + case AOT_DRM_SBR: + case AOT_DRM_MPEG_PS: + FDK_ASSERT(epConfig == 1); + if (nChannels == 1) { + return &node_drm_sce; + } else { + return &node_drm_cpe; + } + break; default: break; } diff --git a/libMpegTPDec/src/tpdec_asc.cpp b/libMpegTPDec/src/tpdec_asc.cpp index bae271e..96a1b35 100644 --- a/libMpegTPDec/src/tpdec_asc.cpp +++ b/libMpegTPDec/src/tpdec_asc.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 @@ -1126,6 +1126,8 @@ TRANSPORTDEC_ERROR EldSpecificConfig_Parse( if ( 0 != ld_sbr_header(asc, hBs, cb) ) { return TRANSPORTDEC_PARSE_ERROR; } + } else { + return TRANSPORTDEC_UNSUPPORTED_FORMAT; } } esc->m_useLdQmfTimeAlign = 0; @@ -1146,7 +1148,7 @@ TRANSPORTDEC_ERROR EldSpecificConfig_Parse( switch (eldExtType) { default: - for(cnt=0; cntm_samplingFrequencyIndex = sfIdx; + self->m_samplingFrequency = SamplingRateTable[sfIdx]; + + if ( sbrFlag ) { + UINT i; + int tmp = -1; + self->m_sbrPresentFlag = 1; + self->m_extensionAudioObjectType = AOT_SBR; + self->m_extensionSamplingFrequency = self->m_samplingFrequency << 1; + for (i=0; i<(sizeof(SamplingRateTable)/sizeof(SamplingRateTable[0])); i++){ + if (SamplingRateTable[i] == self->m_extensionSamplingFrequency){ + tmp = i; + break; + } + } + self->m_extensionSamplingFrequencyIndex = tmp; + } + + switch (audioCoding) { + case 0: /* AAC */ + self->m_aot = AOT_DRM_AAC ; /* Set pseudo AOT for Drm AAC */ + + switch (audioMode) { + case 1: /* parametric stereo */ + self->m_psPresentFlag = 1; + case 0: /* mono */ + self->m_channelConfiguration = 1; + break; + case 2: /* stereo */ + self->m_channelConfiguration = 2; + break; + default: + ErrorStatus = TRANSPORTDEC_PARSE_ERROR; + goto bail; + } + self->m_vcb11Flag = 1; + self->m_hcrFlag = 1; + self->m_samplesPerFrame = 960; + self->m_epConfig = 1; + break; + case 1: /* CELP */ + self->m_aot = AOT_ER_CELP; + self->m_channelConfiguration = 1; + break; + case 2: /* HVXC */ + self->m_aot = AOT_ER_HVXC; + self->m_channelConfiguration = 1; + break; + case 3: /* reserved */ + default: + ErrorStatus = TRANSPORTDEC_PARSE_ERROR; + self->m_aot = AOT_NONE; + break; + } + + if (self->m_psPresentFlag && !self->m_sbrPresentFlag) { + ErrorStatus = TRANSPORTDEC_PARSE_ERROR; + goto bail; + } + } + +bail: + return (ErrorStatus); +} diff --git a/libMpegTPDec/src/tpdec_drm.cpp b/libMpegTPDec/src/tpdec_drm.cpp new file mode 100644 index 0000000..df319e5 --- /dev/null +++ b/libMpegTPDec/src/tpdec_drm.cpp @@ -0,0 +1,146 @@ + +/* ----------------------------------------------------------------------------------------------------------- +Software License for The Fraunhofer FDK AAC Codec Library for Android + +© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. + All rights reserved. + + 1. INTRODUCTION +The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements +the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. +This FDK AAC Codec software is intended to be used on a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual +audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by +independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part +of the MPEG specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) +may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners +individually for the purpose of encoding or decoding bit streams in products that are compliant with +the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license +these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec +software may already be covered under those patent licenses when it is used for those licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, +are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional +applications information and documentation. + +2. COPYRIGHT LICENSE + +Redistribution and use in source and binary forms, with or without modification, are permitted without +payment of copyright license fees provided that you satisfy the following conditions: + +You must retain the complete text of this software license in redistributions of the FDK AAC Codec or +your modifications thereto in source code form. + +You must retain the complete text of this software license in the documentation and/or other materials +provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. +You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +modifications thereto to recipients of copies in binary form. + +The name of Fraunhofer may not be used to endorse or promote products derived from this library without +prior written permission. + +You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec +software or your modifications thereto. + +Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software +and the date of any change. For modified versions of the FDK AAC Codec, the term +"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term +"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." + +3. NO PATENT LICENSE + +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, +ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with +respect to this software. + +You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized +by appropriate patent licenses. + +4. DISCLAIMER + +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors +"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties +of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, +including but not limited to procurement of substitute goods or services; loss of use, data, or profits, +or business interruption, however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of this software, even if +advised of the possibility of such damage. + +5. CONTACT INFORMATION + +Fraunhofer Institute for Integrated Circuits IIS +Attention: Audio and Multimedia Departments - FDK AAC LL +Am Wolfsmantel 33 +91058 Erlangen, Germany + +www.iis.fraunhofer.de/amm +amm-info@iis.fraunhofer.de +----------------------------------------------------------------------------------------------------------- */ + +/***************************** MPEG-4 AAC Decoder ************************** + + Author(s): Christian Griebel + Description: DRM transport stuff + +******************************************************************************/ + +#include "tpdec_drm.h" + + +#include "FDK_bitstream.h" + + + +void drmRead_CrcInit(HANDLE_DRM pDrm) /*!< pointer to drm crc info stucture */ +{ + FDK_ASSERT(pDrm != NULL); + + FDKcrcInit(&pDrm->crcInfo, 0x001d, 0xFFFF, 8); +} + +int drmRead_CrcStartReg( + HANDLE_DRM pDrm, /*!< pointer to drm stucture */ + HANDLE_FDK_BITSTREAM hBs, /*!< handle to current bit buffer structure */ + int mBits /*!< number of bits in crc region */ + ) +{ + FDK_ASSERT(pDrm != NULL); + + FDKcrcReset(&pDrm->crcInfo); + + pDrm->crcReadValue = FDKreadBits(hBs, 8); + + return ( FDKcrcStartReg(&pDrm->crcInfo, hBs, mBits) ); + +} + +void drmRead_CrcEndReg( + HANDLE_DRM pDrm, /*!< pointer to drm crc info stucture */ + HANDLE_FDK_BITSTREAM hBs, /*!< handle to current bit buffer structure */ + int reg /*!< crc region */ + ) +{ + FDK_ASSERT(pDrm != NULL); + + FDKcrcEndReg(&pDrm->crcInfo, hBs, reg); +} + +TRANSPORTDEC_ERROR drmRead_CrcCheck( HANDLE_DRM pDrm ) +{ + TRANSPORTDEC_ERROR ErrorStatus = TRANSPORTDEC_OK; + USHORT crc; + + crc = FDKcrcGetCRC(&pDrm->crcInfo) ^ 0xFF; + if (crc != pDrm->crcReadValue) + { + return (TRANSPORTDEC_CRC_ERROR); + } + + return (ErrorStatus); +} + + diff --git a/libMpegTPDec/src/tpdec_drm.h b/libMpegTPDec/src/tpdec_drm.h new file mode 100644 index 0000000..2161b4c --- /dev/null +++ b/libMpegTPDec/src/tpdec_drm.h @@ -0,0 +1,194 @@ + +/* ----------------------------------------------------------------------------------------------------------- +Software License for The Fraunhofer FDK AAC Codec Library for Android + +© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. + All rights reserved. + + 1. INTRODUCTION +The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements +the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. +This FDK AAC Codec software is intended to be used on a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual +audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by +independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part +of the MPEG specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) +may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners +individually for the purpose of encoding or decoding bit streams in products that are compliant with +the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license +these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec +software may already be covered under those patent licenses when it is used for those licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, +are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional +applications information and documentation. + +2. COPYRIGHT LICENSE + +Redistribution and use in source and binary forms, with or without modification, are permitted without +payment of copyright license fees provided that you satisfy the following conditions: + +You must retain the complete text of this software license in redistributions of the FDK AAC Codec or +your modifications thereto in source code form. + +You must retain the complete text of this software license in the documentation and/or other materials +provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. +You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +modifications thereto to recipients of copies in binary form. + +The name of Fraunhofer may not be used to endorse or promote products derived from this library without +prior written permission. + +You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec +software or your modifications thereto. + +Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software +and the date of any change. For modified versions of the FDK AAC Codec, the term +"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term +"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." + +3. NO PATENT LICENSE + +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, +ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with +respect to this software. + +You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized +by appropriate patent licenses. + +4. DISCLAIMER + +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors +"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties +of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, +including but not limited to procurement of substitute goods or services; loss of use, data, or profits, +or business interruption, however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of this software, even if +advised of the possibility of such damage. + +5. CONTACT INFORMATION + +Fraunhofer Institute for Integrated Circuits IIS +Attention: Audio and Multimedia Departments - FDK AAC LL +Am Wolfsmantel 33 +91058 Erlangen, Germany + +www.iis.fraunhofer.de/amm +amm-info@iis.fraunhofer.de +----------------------------------------------------------------------------------------------------------- */ + +/***************************** MPEG-4 AAC Decoder ************************** + + Author(s): Josef Hoepfl + Description: DRM interface + +******************************************************************************/ + +#ifndef TPDEC_DRM_H +#define TPDEC_DRM_H + +#include "tpdec_lib.h" + + +#include "FDK_crc.h" + +typedef struct { + + FDK_CRCINFO crcInfo; /* CRC state info */ + USHORT crcReadValue; /* CRC value read from bitstream data */ + +} STRUCT_DRM; + +typedef STRUCT_DRM *HANDLE_DRM; + +/*! + \brief Initialize DRM CRC + + The function initialzes the crc buffer and the crc lookup table. + + \return none +*/ +void drmRead_CrcInit( HANDLE_DRM pDrm ); + +/** + * \brief Starts CRC region with a maximum number of bits + * If mBits is positive zero padding will be used for CRC calculation, if there + * are less than mBits bits available. + * If mBits is negative no zero padding is done. + * If mBits is zero the memory for the buffer is allocated dynamically, the + * number of bits is not limited. + * + * \param pDrm DRM data handle + * \param hBs bitstream handle, on which the CRC region referes to + * \param mBits max number of bits in crc region to be considered + * + * \return ID for the created region, -1 in case of an error + */ +int drmRead_CrcStartReg( + HANDLE_DRM pDrm, + HANDLE_FDK_BITSTREAM hBs, + int mBits + ); + +/** + * \brief Ends CRC region identified by reg + * + * \param pDrm DRM data handle + * \param hBs bitstream handle, on which the CRC region referes to + * \param reg CRC regions ID returned by drmRead_CrcStartReg() + * + * \return none + */ +void drmRead_CrcEndReg( + HANDLE_DRM pDrm, + HANDLE_FDK_BITSTREAM hBs, + int reg + ); + +/** + * \brief Check CRC + * + * Checks if the currently calculated CRC matches the CRC field read from the bitstream + * Deletes all CRC regions. + * + * \param pDrm DRM data handle + * + * \return Returns 0 if they are identical otherwise 1 + */ +TRANSPORTDEC_ERROR drmRead_CrcCheck( HANDLE_DRM pDrm ); + +/** + * \brief Check if we have a valid DRM frame at the current bitbuffer position + * + * This function assumes enough bits in buffer for the current frame. + * It reads out the header bits to prepare the bitbuffer for the decode loop. + * In case the header bits show an invalid bitstream/frame, the whole frame is skipped. + * + * \param pDrm DRM data handle which is filled with parsed DRM header data + * \param bs handle of bitstream from whom the DRM header is read + * + * \return error status + */ +TRANSPORTDEC_ERROR drmRead_DecodeHeader( + HANDLE_DRM pDrm, + HANDLE_FDK_BITSTREAM bs + ); + +/** + * \brief Parse a Drm specific SDC audio config from a given bitstream handle. + * + * \param pAsc A pointer to an allocated CSAudioSpecificConfig struct. + * \param hBs Bitstream handle. + * + * \return Total element count including all SCE, CPE and LFE. + */ +TRANSPORTDEC_ERROR DrmRawSdcAudioConfig_Parse( CSAudioSpecificConfig *pAsc, + HANDLE_FDK_BITSTREAM hBs ); + + + +#endif /* TPDEC_DRM_H */ diff --git a/libMpegTPDec/src/tpdec_lib.cpp b/libMpegTPDec/src/tpdec_lib.cpp index 950af64..24f755b 100644 --- a/libMpegTPDec/src/tpdec_lib.cpp +++ b/libMpegTPDec/src/tpdec_lib.cpp @@ -102,6 +102,7 @@ amm-info@iis.fraunhofer.de #include "tpdec_latm.h" +#include "tpdec_drm.h" #define MODULE_NAME "transportDec" @@ -113,6 +114,7 @@ typedef union { CLatmDemux latm; + STRUCT_DRM drm; } transportdec_parser_t; @@ -182,6 +184,9 @@ HANDLE_TRANSPORTDEC transportDec_Open( const TRANSPORT_TYPE transportFmt, const hInput->numberOfRawDataBlocks = 0; break; + case TT_DRM: + drmRead_CrcInit(&hInput->parser.drm); + break; case TT_MP4_LATM_MCP0: case TT_MP4_LATM_MCP1: @@ -253,6 +258,18 @@ TRANSPORTDEC_ERROR transportDec_OutOfBandConfig(HANDLE_TRANSPORTDEC hTp, UCHAR * } } break; + case TT_DRM: + fConfigFound = 1; + err = DrmRawSdcAudioConfig_Parse(&hTp->asc[layer], hBs); + if (err == TRANSPORTDEC_OK) { + int errC; + + errC = hTp->callbacks.cbUpdateConfig(hTp->callbacks.cbUpdateConfigData, &hTp->asc[layer]); + if (errC != 0) { + err = TRANSPORTDEC_PARSE_ERROR; + } + } + break; } if (err == TRANSPORTDEC_OK && fConfigFound) { @@ -1083,6 +1100,7 @@ TRANSPORTDEC_ERROR transportDec_ReadAccessUnit( const HANDLE_TRANSPORTDEC hTp, c break; case TT_MP4_RAW: + case TT_DRM: /* One Access Unit was filled into buffer. So get the length out of the buffer. */ hTp->auLength[layer] = FDKgetValidBits(hBs); @@ -1283,6 +1301,7 @@ TRANSPORTDEC_ERROR transportDec_GetLibInfo( LIB_INFO *info ) | CAPF_LATM | CAPF_LOAS | CAPF_RAWPACKETS + | CAPF_DRM ; return TRANSPORTDEC_OK; /* FDKERR_NOERROR; */ @@ -1294,6 +1313,8 @@ int transportDec_CrcStartReg(HANDLE_TRANSPORTDEC pTp, INT mBits) switch (pTp->transportFmt) { case TT_MP4_ADTS: return adtsRead_CrcStartReg(&pTp->parser.adts, &pTp->bitStream[0], mBits); + case TT_DRM: + return drmRead_CrcStartReg(&pTp->parser.drm, &pTp->bitStream[0], mBits); default: return 0; } @@ -1305,6 +1326,9 @@ void transportDec_CrcEndReg(HANDLE_TRANSPORTDEC pTp, INT reg) case TT_MP4_ADTS: adtsRead_CrcEndReg(&pTp->parser.adts, &pTp->bitStream[0], reg); break; + case TT_DRM: + drmRead_CrcEndReg(&pTp->parser.drm, &pTp->bitStream[0], reg); + break; default: break; } @@ -1321,6 +1345,9 @@ TRANSPORTDEC_ERROR transportDec_CrcCheck(HANDLE_TRANSPORTDEC pTp) transportDec_AdjustEndOfAccessUnit(pTp); } return adtsRead_CrcCheck(&pTp->parser.adts); + case TT_DRM: + return drmRead_CrcCheck(&pTp->parser.drm); + break; default: return TRANSPORTDEC_OK; } diff --git a/libMpegTPDec/src/version b/libMpegTPDec/src/version index 18fc9ba..75e22c9 100644 --- a/libMpegTPDec/src/version +++ b/libMpegTPDec/src/version @@ -2,7 +2,7 @@ /* library info */ #define TP_LIB_VL0 2 #define TP_LIB_VL1 3 -#define TP_LIB_VL2 5 +#define TP_LIB_VL2 7 #define TP_LIB_TITLE "MPEG Transport" #ifdef __ANDROID__ #define TP_LIB_BUILD_DATE "" diff --git a/libSBRdec/include/sbrdecoder.h b/libSBRdec/include/sbrdecoder.h index 174fb5c..3bb9ba3 100644 --- a/libSBRdec/include/sbrdecoder.h +++ b/libSBRdec/include/sbrdecoder.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 @@ -262,6 +262,7 @@ void sbrDecoder_drcDisable ( HANDLE_SBRDECODER self, * into *count if a payload length is given (byPayLen > 0). If no SBR payload length is * given (bsPayLen < 0) then the bit stream position on return will be random after this * function call in case of errors, and any further decoding will be completely pointless. + * This function accepts either normal ordered SBR data or reverse ordered DRM SBR data. * * \param self SBR decoder handle. * \param hBs Bit stream handle as data source. diff --git a/libSBRdec/src/env_calc.cpp b/libSBRdec/src/env_calc.cpp index ade57fc..fa5330a 100644 --- a/libSBRdec/src/env_calc.cpp +++ b/libSBRdec/src/env_calc.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 @@ -151,13 +151,13 @@ typedef struct } ENV_CALC_NRGS; -/*static*/ void equalizeFiltBufferExp(FIXP_DBL *filtBuffer, +static void equalizeFiltBufferExp(FIXP_DBL *filtBuffer, SCHAR *filtBuffer_e, FIXP_DBL *NrgGain, SCHAR *NrgGain_e, int subbands); -/*static*/ void calcNrgPerSubband(FIXP_DBL **analysBufferReal, +static void calcNrgPerSubband(FIXP_DBL **analysBufferReal, FIXP_DBL **analysBufferImag, int lowSubband, int highSubband, int start_pos, int next_pos, @@ -165,7 +165,7 @@ ENV_CALC_NRGS; FIXP_DBL *nrgEst, SCHAR *nrgEst_e ); -/*static*/ void calcNrgPerSfb(FIXP_DBL **analysBufferReal, +static void calcNrgPerSfb(FIXP_DBL **analysBufferReal, FIXP_DBL **analysBufferImag, int nSfb, UCHAR *freqBandTable, @@ -174,13 +174,13 @@ ENV_CALC_NRGS; FIXP_DBL *nrg_est, SCHAR *nrg_est_e ); -/*static*/ void calcSubbandGain(FIXP_DBL nrgRef, SCHAR nrgRef_e, ENV_CALC_NRGS* nrgs, int c, +static void calcSubbandGain(FIXP_DBL nrgRef, SCHAR nrgRef_e, ENV_CALC_NRGS* nrgs, int c, FIXP_DBL tmpNoise, SCHAR tmpNoise_e, UCHAR sinePresentFlag, UCHAR sineMapped, int noNoiseFlag); -/*static*/ void calcAvgGain(ENV_CALC_NRGS* nrgs, +static void calcAvgGain(ENV_CALC_NRGS* nrgs, int lowSubband, int highSubband, FIXP_DBL *sumRef_m, @@ -188,7 +188,7 @@ ENV_CALC_NRGS; FIXP_DBL *ptrAvgGain_m, SCHAR *ptrAvgGain_e); -/*static*/ void adjustTimeSlotLC(FIXP_DBL *ptrReal, +static void adjustTimeSlot_EldGrid(FIXP_DBL *ptrReal, ENV_CALC_NRGS* nrgs, UCHAR *ptrHarmIndex, int lowSubbands, @@ -196,8 +196,17 @@ ENV_CALC_NRGS; int scale_change, int noNoiseFlag, int *ptrPhaseIndex, - int fCldfb); -/*static*/ void adjustTimeSlotHQ(FIXP_DBL *ptrReal, + int scale_diff_low); + +static void adjustTimeSlotLC(FIXP_DBL *ptrReal, + ENV_CALC_NRGS* nrgs, + UCHAR *ptrHarmIndex, + int lowSubbands, + int noSubbands, + int scale_change, + int noNoiseFlag, + int *ptrPhaseIndex); +static void adjustTimeSlotHQ(FIXP_DBL *ptrReal, FIXP_DBL *ptrImag, HANDLE_SBR_CALCULATE_ENVELOPE h_sbr_cal_env, ENV_CALC_NRGS* nrgs, @@ -224,7 +233,7 @@ ENV_CALC_NRGS; Additionally, the flags in harmFlagsPrev are being updated by this function for the next frame. */ -/*static*/ void mapSineFlags(UCHAR *freqBandTable, /*!< Band borders (there's only 1 flag per band) */ +static void mapSineFlags(UCHAR *freqBandTable, /*!< Band borders (there's only 1 flag per band) */ int nSfb, /*!< Number of bands in the table */ UCHAR *addHarmonics, /*!< vector with 1 flag per sfb */ int *harmFlagsPrev, /*!< Packed 'addHarmonics' */ @@ -990,7 +999,6 @@ calculateSbrEnvelope (QMF_SCALE_FACTOR *sbrScaleFactor, /*!< Scaling /* Prevent the smoothing filter from running on constant levels */ if (j-start_pos < smooth_length) smooth_ratio = FDK_sbrDecoder_sbr_smoothFilter[j-start_pos]; - else smooth_ratio = FL2FXCONST_SGL(0.0f); @@ -1007,7 +1015,8 @@ calculateSbrEnvelope (QMF_SCALE_FACTOR *sbrScaleFactor, /*!< Scaling } else { - adjustTimeSlotLC(&analysBufferReal[j][lowSubband], + if (flags & SBRDEC_ELD_GRID) { + adjustTimeSlot_EldGrid(&analysBufferReal[j][lowSubband], pNrgs, &h_sbr_cal_env->harmIndex, lowSubband, @@ -1015,7 +1024,18 @@ calculateSbrEnvelope (QMF_SCALE_FACTOR *sbrScaleFactor, /*!< Scaling scale_change, noNoiseFlag, &h_sbr_cal_env->phaseIndex, - (flags & SBRDEC_ELD_GRID)); + EXP2SCALE(adj_e) - sbrScaleFactor->lb_scale); + } else + { + adjustTimeSlotLC(&analysBufferReal[j][lowSubband], + pNrgs, + &h_sbr_cal_env->harmIndex, + lowSubband, + noSubbands, + scale_change, + noNoiseFlag, + &h_sbr_cal_env->phaseIndex); + } } } // for @@ -1176,7 +1196,7 @@ resetSbrEnvelopeCalc (HANDLE_SBR_CALCULATE_ENVELOPE hCalEnv) /*!< pointer to env can be performed. This function is called once for each envelope before adjusting. */ -/*static*/ void equalizeFiltBufferExp(FIXP_DBL *filtBuffer, /*!< bufferd gains */ +static void equalizeFiltBufferExp(FIXP_DBL *filtBuffer, /*!< bufferd gains */ SCHAR *filtBuffer_e, /*!< exponents of bufferd gains */ FIXP_DBL *nrgGain, /*!< gains for current envelope */ SCHAR *nrgGain_e, /*!< exponents of gains for current envelope */ @@ -1331,7 +1351,7 @@ FIXP_DBL maxSubbandSample( FIXP_DBL ** re, /*!< Real part of input and output This function is used when interpolFreq is true. */ -/*static*/ void calcNrgPerSubband(FIXP_DBL **analysBufferReal, /*!< Real part of subband samples */ +static void calcNrgPerSubband(FIXP_DBL **analysBufferReal, /*!< Real part of subband samples */ FIXP_DBL **analysBufferImag, /*!< Imaginary part of subband samples */ int lowSubband, /*!< Begin of the SBR frequency range */ int highSubband, /*!< High end of the SBR frequency range */ @@ -1452,7 +1472,7 @@ FIXP_DBL maxSubbandSample( FIXP_DBL ** re, /*!< Real part of input and output This function is used when interpolFreq is false. */ -/*static*/ void calcNrgPerSfb(FIXP_DBL **analysBufferReal, /*!< Real part of subband samples */ +static void calcNrgPerSfb(FIXP_DBL **analysBufferReal, /*!< Real part of subband samples */ FIXP_DBL **analysBufferImag, /*!< Imaginary part of subband samples */ int nSfb, /*!< Number of scale factor bands */ UCHAR *freqBandTable, /*!< First Subband for each Sfb */ @@ -1585,7 +1605,7 @@ FIXP_DBL maxSubbandSample( FIXP_DBL ** re, /*!< Real part of input and output The resulting energy gain is given by mantissa and exponent. */ -/*static*/ void calcSubbandGain(FIXP_DBL nrgRef, /*!< Reference Energy according to envelope data */ +static void calcSubbandGain(FIXP_DBL nrgRef, /*!< Reference Energy according to envelope data */ SCHAR nrgRef_e, /*!< Reference Energy according to envelope data (exponent) */ ENV_CALC_NRGS* nrgs, int i, @@ -1689,7 +1709,7 @@ FIXP_DBL maxSubbandSample( FIXP_DBL ** re, /*!< Real part of input and output The result is used as a relative limit for all gains within the current "limiter band" (a certain frequency range). */ -/*static*/ void calcAvgGain(ENV_CALC_NRGS* nrgs, +static void calcAvgGain(ENV_CALC_NRGS* nrgs, int lowSubband, /*!< Begin of the limiter band */ int highSubband, /*!< High end of the limiter band */ FIXP_DBL *ptrSumRef, @@ -1728,21 +1748,101 @@ FIXP_DBL maxSubbandSample( FIXP_DBL ** re, /*!< Real part of input and output *ptrSumRef_e = sumRef_e; } +static void adjustTimeSlot_EldGrid( + FIXP_DBL *ptrReal, /*!< Subband samples to be adjusted, real part */ + ENV_CALC_NRGS* nrgs, + UCHAR *ptrHarmIndex, /*!< Harmonic index */ + int lowSubband, /*!< Lowest QMF-channel in the currently used SBR range. */ + int noSubbands, /*!< Number of QMF subbands */ + int scale_change, /*!< Number of bits to shift adjusted samples */ + int noNoiseFlag, /*!< Flag to suppress noise addition */ + int *ptrPhaseIndex, /*!< Start index to random number array */ + int scale_diff_low) /*!< */ +{ + int k; + FIXP_DBL signalReal, sbNoise; + int tone_count = 0; + + FIXP_DBL *pGain = nrgs->nrgGain; /*!< Gains of current envelope */ + FIXP_DBL *pNoiseLevel = nrgs->noiseLevel; /*!< Noise levels of current envelope */ + FIXP_DBL *pSineLevel = nrgs->nrgSine; /*!< Sine levels */ + + int phaseIndex = *ptrPhaseIndex; + UCHAR harmIndex = *ptrHarmIndex; + + static const INT harmonicPhase [2][4] = { + { 1, 0, -1, 0}, + { 0, 1, 0, -1} + }; + + static const FIXP_DBL harmonicPhaseX [2][4] = { + { FL2FXCONST_DBL(2.0*1.245183154539139e-001), FL2FXCONST_DBL(2.0*-1.123767859325028e-001), FL2FXCONST_DBL(2.0*-1.245183154539139e-001), FL2FXCONST_DBL(2.0* 1.123767859325028e-001) }, + { FL2FXCONST_DBL(2.0*1.245183154539139e-001), FL2FXCONST_DBL(2.0* 1.123767859325028e-001), FL2FXCONST_DBL(2.0*-1.245183154539139e-001), FL2FXCONST_DBL(2.0*-1.123767859325028e-001) } + }; + + for (k=0; k < noSubbands; k++) { + + phaseIndex = (phaseIndex + 1) & (SBR_NF_NO_RANDOM_VAL - 1); + + if( (pSineLevel[0] != FL2FXCONST_DBL(0.0f)) || (noNoiseFlag == 1) ){ + sbNoise = FL2FXCONST_DBL(0.0f); + } else { + sbNoise = pNoiseLevel[0]; + } + + signalReal = fMultDiv2(*ptrReal,*pGain) << ((int)scale_change); + + signalReal += (fMultDiv2(FDK_sbrDecoder_sbr_randomPhase[phaseIndex][0], sbNoise)<<4); + + signalReal += pSineLevel[0] * harmonicPhase[0][harmIndex]; + + *ptrReal = signalReal; + + if (k == 0) { + *(ptrReal-1) += scaleValue(fMultDiv2(harmonicPhaseX[lowSubband&1][harmIndex], pSineLevel[0]), -scale_diff_low) ; + if (k < noSubbands - 1) { + *(ptrReal) += fMultDiv2(pSineLevel[1], harmonicPhaseX[(lowSubband+1)&1][harmIndex]); + } + } + if (k > 0 && k < noSubbands - 1 && tone_count < 16) { + *(ptrReal) += fMultDiv2(pSineLevel[- 1], harmonicPhaseX [(lowSubband+k)&1] [harmIndex]); + *(ptrReal) += fMultDiv2(pSineLevel[+ 1], harmonicPhaseX [(lowSubband+k+1)&1][harmIndex]); + } + if (k == noSubbands - 1 && tone_count < 16) { + if (k > 0) { + *(ptrReal) += fMultDiv2(pSineLevel[- 1], harmonicPhaseX [(lowSubband+k)&1][harmIndex]); + } + if (k + lowSubband + 1< 63) { + *(ptrReal+1) += fMultDiv2(pSineLevel[0], harmonicPhaseX[(lowSubband+k+1)&1][harmIndex]); + } + } + + if(pSineLevel[0] != FL2FXCONST_DBL(0.0f)){ + tone_count++; + } + ptrReal++; + pNoiseLevel++; + pGain++; + pSineLevel++; + } + + *ptrHarmIndex = (harmIndex + 1) & 3; + *ptrPhaseIndex = phaseIndex & (SBR_NF_NO_RANDOM_VAL - 1); +} /*! \brief Amplify one timeslot of the signal with the calculated gains and add the noisefloor. */ -/*static*/ void adjustTimeSlotLC(FIXP_DBL *ptrReal, /*!< Subband samples to be adjusted, real part */ +static void adjustTimeSlotLC(FIXP_DBL *ptrReal, /*!< Subband samples to be adjusted, real part */ ENV_CALC_NRGS* nrgs, UCHAR *ptrHarmIndex, /*!< Harmonic index */ int lowSubband, /*!< Lowest QMF-channel in the currently used SBR range. */ int noSubbands, /*!< Number of QMF subbands */ int scale_change, /*!< Number of bits to shift adjusted samples */ int noNoiseFlag, /*!< Flag to suppress noise addition */ - int *ptrPhaseIndex, /*!< Start index to random number array */ - int fCldfb) /*!< CLDFB 80 flag */ + int *ptrPhaseIndex) /*!< Start index to random number array */ { FIXP_DBL *pGain = nrgs->nrgGain; /*!< Gains of current envelope */ FIXP_DBL *pNoiseLevel = nrgs->noiseLevel; /*!< Noise levels of current envelope */ @@ -1775,41 +1875,10 @@ FIXP_DBL maxSubbandSample( FIXP_DBL ** re, /*!< Real part of input and output sineLevelNext = (noSubbands > 1) ? pSineLevel[0] : FL2FXCONST_DBL(0.0f); if (sineLevel!=FL2FXCONST_DBL(0.0f)) tone_count++; - else if (!noNoiseFlag) /* Add noisefloor to the amplified signal */ signalReal += (fMultDiv2(FDK_sbrDecoder_sbr_randomPhase[index][0], pNoiseLevel[0])<<4); - if (fCldfb) { - - if (!(harmIndex&0x1)) { - /* harmIndex 0,2 */ - signalReal += (harmIndex&0x2) ? -sineLevel : sineLevel; - *ptrReal++ = signalReal; - } - else { - /* harmIndex 1,3 in combination with freqInvFlag */ - int shift = (int) (scale_change+1); - shift = (shift>=0) ? fixMin(DFRACT_BITS-1,shift) : fixMax(-(DFRACT_BITS-1),shift); - - FIXP_DBL tmp1 = scaleValue( fMultDiv2(C1_CLDFB, sineLevel), -shift ); - - FIXP_DBL tmp2 = fMultDiv2(C1_CLDFB, sineLevelNext); - - - /* save switch and compare operations and reduce to XOR statement */ - if ( ((harmIndex>>1)&0x1)^freqInvFlag) { - *(ptrReal-1) += tmp1; - signalReal -= tmp2; - } else { - *(ptrReal-1) -= tmp1; - signalReal += tmp2; - } - *ptrReal++ = signalReal; - freqInvFlag = !freqInvFlag; - } - - } else { if (!(harmIndex&0x1)) { /* harmIndex 0,2 */ @@ -1933,8 +2002,9 @@ FIXP_DBL maxSubbandSample( FIXP_DBL ** re, /*!< Real part of input and output *ptrHarmIndex = (harmIndex + 1) & 3; *ptrPhaseIndex = index & (SBR_NF_NO_RANDOM_VAL - 1); } -void adjustTimeSlotHQ(FIXP_DBL *RESTRICT ptrReal, /*!< Subband samples to be adjusted, real part */ - FIXP_DBL *RESTRICT ptrImag, /*!< Subband samples to be adjusted, imag part */ +static void adjustTimeSlotHQ( + FIXP_DBL *RESTRICT ptrReal, /*!< Subband samples to be adjusted, real part */ + FIXP_DBL *RESTRICT ptrImag, /*!< Subband samples to be adjusted, imag part */ HANDLE_SBR_CALCULATE_ENVELOPE h_sbr_cal_env, ENV_CALC_NRGS* nrgs, int lowSubband, /*!< Lowest QMF-channel in the currently used SBR range. */ @@ -2137,7 +2207,6 @@ ResetLimiterBands ( UCHAR *limiterBandTable, /*!< Resulting band borders in QM UCHAR workLimiterBandTable[MAX_FREQ_COEFFS / 2 + MAX_NUM_PATCHES + 1]; int patchBorders[MAX_NUM_PATCHES + 1]; int kx, k2; - FIXP_DBL temp; int lowSubband = freqBandTable[0]; int highSubband = freqBandTable[noFreqBands]; @@ -2169,13 +2238,32 @@ ResetLimiterBands ( UCHAR *limiterBandTable, /*!< Resulting band borders in QM while (hiLimIndex <= tempNoLim) { + FIXP_DBL div_m, oct_m, temp; + INT div_e = 0, oct_e = 0, temp_e = 0; + k2 = workLimiterBandTable[hiLimIndex] + lowSubband; kx = workLimiterBandTable[loLimIndex] + lowSubband; - temp = FX_SGL2FX_DBL(FDK_getNumOctavesDiv8(kx,k2)); /* Number of octaves */ - temp = fMult(temp, FDK_sbrDecoder_sbr_limiterBandsPerOctaveDiv4[limiterBands]); + div_m = fDivNorm(k2, kx, &div_e); + + /* calculate number of octaves */ + oct_m = fLog2(div_m, div_e, &oct_e); + + /* multiply with limiterbands per octave */ + /* values 1, 1.2, 2, 3 -> scale factor of 2 */ + temp = fMultNorm(oct_m, FDK_sbrDecoder_sbr_limiterBandsPerOctaveDiv4_DBL[limiterBands], &temp_e); + + /* overall scale factor of temp ist addition of scalefactors from log2 calculation, + limiter bands scalefactor (2) and limiter bands multiplication */ + temp_e += oct_e + 2; + + /* div can be a maximum of 64 (k2 = 64 and kx = 1) + -> oct can be a maximum of 6 + -> temp can be a maximum of 18 (as limiterBandsPerOctoave is a maximum factor of 3) + -> we need a scale factor of 5 for comparisson + */ + if (temp >> (5 - temp_e) < FL2FXCONST_DBL (0.49f) >> 5) { - if (temp < FL2FXCONST_DBL (0.49f)>>5) { if (workLimiterBandTable[hiLimIndex] == workLimiterBandTable[loLimIndex]) { workLimiterBandTable[hiLimIndex] = highSubband; nBands--; diff --git a/libSBRdec/src/env_dec.cpp b/libSBRdec/src/env_dec.cpp index 24b2d3b..c65c169 100644 --- a/libSBRdec/src/env_dec.cpp +++ b/libSBRdec/src/env_dec.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 @@ -369,7 +369,7 @@ leanSbrConcealment(HANDLE_SBR_HEADER_DATA hHeaderData, /*!< Static control d FIXP_SGL step; /* speed of fade */ int i; - int currentStartPos = h_prev_data->stopPos - hHeaderData->numberTimeSlots; + int currentStartPos = FDKmax(0, h_prev_data->stopPos - hHeaderData->numberTimeSlots); int currentStopPos = hHeaderData->numberTimeSlots; diff --git a/libSBRdec/src/env_extr.cpp b/libSBRdec/src/env_extr.cpp index 6cb0b99..dacd951 100644 --- a/libSBRdec/src/env_extr.cpp +++ b/libSBRdec/src/env_extr.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 @@ -327,7 +327,7 @@ sbrGetHeaderData (HANDLE_SBR_HEADER_DATA hHeaderData, } /* Look for new settings. IEC 14496-3, 4.6.18.3.1 */ - if(hHeaderData->syncState != SBR_ACTIVE || + if(hHeaderData->syncState < SBR_HEADER || lastHeader.startFreq != pBsData->startFreq || lastHeader.stopFreq != pBsData->stopFreq || lastHeader.freqScale != pBsData->freqScale || diff --git a/libSBRdec/src/env_extr.h b/libSBRdec/src/env_extr.h index ab6b704..0518ea9 100644 --- a/libSBRdec/src/env_extr.h +++ b/libSBRdec/src/env_extr.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 @@ -125,6 +125,7 @@ amm-info@iis.fraunhofer.de typedef enum { HEADER_NOT_PRESENT, + HEADER_ERROR, HEADER_OK, HEADER_RESET } @@ -132,10 +133,10 @@ SBR_HEADER_STATUS; typedef enum { - SBR_NOT_INITIALIZED, - UPSAMPLING, - SBR_HEADER, - SBR_ACTIVE + SBR_NOT_INITIALIZED = 0, + UPSAMPLING = 1, + SBR_HEADER = 2, + SBR_ACTIVE = 3 } SBR_SYNC_STATE; @@ -179,6 +180,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_SYNTAX_DRM 2048 /* Flag indicating that DRM30/DRM+ reverse syntax is being 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/sbr_dec.cpp b/libSBRdec/src/sbr_dec.cpp index 1282338..0864348 100644 --- a/libSBRdec/src/sbr_dec.cpp +++ b/libSBRdec/src/sbr_dec.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 @@ -225,7 +225,14 @@ static void changeQmfType( HANDLE_SBR_DEC hSbrDec, /*!< hand } if (resetAnaQmf) { - int qmfErr = qmfInitAnalysisFilterBank ( + QMF_FILTER_BANK prvAnaQmf; + int qmfErr; + + /* Store current configuration */ + FDKmemcpy(&prvAnaQmf, &hSbrDec->AnalysiscQMF, sizeof(QMF_FILTER_BANK)); + + /* Reset analysis QMF */ + qmfErr = qmfInitAnalysisFilterBank ( &hSbrDec->AnalysiscQMF, hSbrDec->anaQmfStates, hSbrDec->AnalysiscQMF.no_col, @@ -234,13 +241,22 @@ static void changeQmfType( HANDLE_SBR_DEC hSbrDec, /*!< hand hSbrDec->AnalysiscQMF.no_channels, anaQmfFlags | QMF_FLAG_KEEP_STATES ); + if (qmfErr != 0) { - FDK_ASSERT(0); + /* Restore old configuration of analysis QMF */ + FDKmemcpy(&hSbrDec->AnalysiscQMF, &prvAnaQmf, sizeof(QMF_FILTER_BANK)); } } if (resetSynQmf) { - int qmfErr = qmfInitSynthesisFilterBank ( + QMF_FILTER_BANK prvSynQmf; + int qmfErr; + + /* Store current configuration */ + FDKmemcpy(&prvSynQmf, &hSbrDec->SynthesisQMF, sizeof(QMF_FILTER_BANK)); + + /* Reset synthesis QMF */ + qmfErr = qmfInitSynthesisFilterBank ( &hSbrDec->SynthesisQMF, hSbrDec->pSynQmfStates, hSbrDec->SynthesisQMF.no_col, @@ -251,7 +267,8 @@ static void changeQmfType( HANDLE_SBR_DEC hSbrDec, /*!< hand ); if (qmfErr != 0) { - FDK_ASSERT(0); + /* Restore old configuration of synthesis QMF */ + FDKmemcpy(&hSbrDec->SynthesisQMF, &prvSynQmf, sizeof(QMF_FILTER_BANK)); } } } @@ -321,7 +338,8 @@ sbr_dec ( HANDLE_SBR_DEC hSbrDec, /*!< handle to Decoder channel */ HANDLE_SBR_PREV_FRAME_DATA hPrevFrameData, /*!< Some control data of last frame */ const int applyProcessing, /*!< Flag for SBR operation */ HANDLE_PS_DEC h_ps_d, - const UINT flags + const UINT flags, + const int codecFrameSize ) { int i, slot, reserve; @@ -348,6 +366,33 @@ sbr_dec ( HANDLE_SBR_DEC hSbrDec, /*!< handle to Decoder channel */ if (flags & SBRDEC_ELD_GRID) { /* Choose the right low delay filter bank */ changeQmfType( hSbrDec, (flags & SBRDEC_LD_MPS_QMF) ? 1 : 0 ); + + /* If the LD-MPS QMF is not available delay the signal by (96-48*ldSbrSamplingRate) + * samples according to ISO/IEC 14496-3:2009/FDAM 2:2010(E) chapter 4.5.2.13. */ + if ( (flags & SBRDEC_LD_MPS_QMF) + && (hSbrDec->AnalysiscQMF.flags & QMF_FLAG_CLDFB) ) + { + INT_PCM *pDlyBuf = hSbrDec->coreDelayBuf; /* DLYBUF */ + int smpl, delay = 96 >> (!(flags & SBRDEC_DOWNSAMPLE) ? 1 : 0); + /* Create TMPBUF */ + C_AALLOC_SCRATCH_START(pcmTemp, INT_PCM, (96)); + /* Copy delay samples from INBUF to TMPBUF */ + for (smpl = 0; smpl < delay; smpl += 1) { + pcmTemp[smpl] = timeIn[(codecFrameSize-delay+smpl)*strideIn]; + } + /* Move input signal remainder to the very end of INBUF */ + for (smpl = (codecFrameSize-delay-1)*strideIn; smpl >= 0; smpl -= strideIn) { + timeIn[smpl+delay] = timeIn[smpl]; + } + /* Copy delayed samples from last frame from DLYBUF to the very beginning of INBUF */ + for (smpl = 0; smpl < delay; smpl += 1) { + timeIn[smpl*strideIn] = pDlyBuf[smpl]; + } + /* Copy TMPBUF to DLYBUF */ + FDKmemcpy(pDlyBuf, pcmTemp, delay*sizeof(INT_PCM)); + /* Destory TMPBUF */ + C_AALLOC_SCRATCH_END(pcmTemp, INT_PCM, (96)); + } } /* @@ -761,7 +806,7 @@ createSbrDec (SBR_CHANNEL * hSbrChannel, { int qmfErr; /* Adapted QMF analysis post-twiddles for down-sampled HQ SBR */ - const UINT downSampledFlag = (downsampleFac==2) ? QMF_FLAG_DOWNSAMPLED : 0; + const UINT downSampledFlag = (flags & SBRDEC_DOWNSAMPLE) ? QMF_FLAG_DOWNSAMPLED : 0; qmfErr = qmfInitAnalysisFilterBank ( &hs->AnalysiscQMF, @@ -836,6 +881,9 @@ createSbrDec (SBR_CHANNEL * hSbrChannel, } } + /* Clear input delay line */ + FDKmemclear(hs->coreDelayBuf, (96)*sizeof(INT_PCM)); + /* assign qmf time slots */ assignTimeSlots( &hSbrChannel->SbrDec, hHeaderData->numberTimeSlots * hHeaderData->timeStep, qmfFlags & QMF_FLAG_LP); diff --git a/libSBRdec/src/sbr_dec.h b/libSBRdec/src/sbr_dec.h index 175e7b2..edde637 100644 --- a/libSBRdec/src/sbr_dec.h +++ b/libSBRdec/src/sbr_dec.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 @@ -118,6 +118,9 @@ typedef struct FIXP_DBL * WorkBuffer1; FIXP_DBL * WorkBuffer2; + /* Delayed time input signal needed to align CLDFD with LD-MPS QMF. */ + INT_PCM coreDelayBuf[(96)]; + /* QMF filter states */ FIXP_QAS anaQmfStates[(320)]; FIXP_QSS * pSynQmfStates; @@ -182,7 +185,8 @@ sbr_dec (HANDLE_SBR_DEC hSbrDec, /*!< handle to Decoder channel */ HANDLE_SBR_PREV_FRAME_DATA hPrevFrameData, /*!< Some control data of last frame */ const int applyProcessing, /*!< Flag for SBR operation */ HANDLE_PS_DEC h_ps_d, - const UINT flags + const UINT flags, + const int codecFrameSize ); diff --git a/libSBRdec/src/sbr_ram.h b/libSBRdec/src/sbr_ram.h index f12631d..7ab5044 100644 --- a/libSBRdec/src/sbr_ram.h +++ b/libSBRdec/src/sbr_ram.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 @@ -135,6 +135,7 @@ struct SBR_DECODER_INSTANCE USHORT codecFrameSize; UCHAR synDownsampleFac; UCHAR numDelayFrames; /* The current number of additional delay frames used for processing. */ + UCHAR numFlushedFrames; /* The variable counts the number of frames which are flushed consecutively. */ UINT flags; diff --git a/libSBRdec/src/sbr_rom.cpp b/libSBRdec/src/sbr_rom.cpp index e84c3cd..c48ce35 100644 --- a/libSBRdec/src/sbr_rom.cpp +++ b/libSBRdec/src/sbr_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 @@ -189,6 +189,15 @@ const FIXP_SGL FDK_sbrDecoder_sbr_limiterBandsPerOctaveDiv4[4] = FL2FXCONST_SGL(3.0f / 4.0f) }; +/*! Constants for calculating the number of limiter bands */ +const FIXP_DBL FDK_sbrDecoder_sbr_limiterBandsPerOctaveDiv4_DBL[4] = +{ + FL2FXCONST_DBL(1.0f / 4.0f), + FL2FXCONST_DBL(1.2f / 4.0f), + FL2FXCONST_DBL(2.0f / 4.0f), + FL2FXCONST_DBL(3.0f / 4.0f) +}; + /*! Ratio of old gains and noise levels for the first 4 timeslots of an envelope */ const FIXP_SGL FDK_sbrDecoder_sbr_smoothFilter[4] = { FL2FXCONST_SGL(0.66666666666666f), diff --git a/libSBRdec/src/sbr_rom.h b/libSBRdec/src/sbr_rom.h index c318870..1f800bc 100644 --- a/libSBRdec/src/sbr_rom.h +++ b/libSBRdec/src/sbr_rom.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 @@ -124,6 +124,7 @@ extern const FIXP_DBL FDK_sbrDecoder_sbr_whFactorsTable[NUM_WHFACTOR_TABLE_ENTRI extern const FIXP_SGL FDK_sbrDecoder_sbr_limGains_m[4]; extern const UCHAR FDK_sbrDecoder_sbr_limGains_e[4]; extern const FIXP_SGL FDK_sbrDecoder_sbr_limiterBandsPerOctaveDiv4[4]; +extern const FIXP_DBL FDK_sbrDecoder_sbr_limiterBandsPerOctaveDiv4_DBL[4]; extern const FIXP_SGL FDK_sbrDecoder_sbr_smoothFilter[4]; extern const FIXP_SGL FDK_sbrDecoder_sbr_randomPhase[SBR_NF_NO_RANDOM_VAL][2]; extern const FIXP_SGL harmonicPhaseX [2][4]; diff --git a/libSBRdec/src/sbrdecoder.cpp b/libSBRdec/src/sbrdecoder.cpp index e15145a..f9ded54 100644 --- a/libSBRdec/src/sbrdecoder.cpp +++ b/libSBRdec/src/sbrdecoder.cpp @@ -128,6 +128,7 @@ amm-info@iis.fraunhofer.de #include "lpp_tran.h" #include "transcendent.h" +#include "FDK_crc.h" #include "sbrdec_drc.h" @@ -137,7 +138,7 @@ amm-info@iis.fraunhofer.de /* Decoder library info */ #define SBRDECODER_LIB_VL0 2 #define SBRDECODER_LIB_VL1 2 -#define SBRDECODER_LIB_VL2 7 +#define SBRDECODER_LIB_VL2 12 #define SBRDECODER_LIB_TITLE "SBR Decoder" #ifdef __ANDROID__ #define SBRDECODER_LIB_BUILD_DATE "" @@ -194,6 +195,33 @@ static void copySbrHeader( HANDLE_SBR_HEADER_DATA hDst, const HANDLE_SBR_HEADER_ hDst->freqBandData.freqBandTable[1] = hDst->freqBandData.freqBandTableHi; } +static int compareSbrHeader( const HANDLE_SBR_HEADER_DATA hHdr1, const HANDLE_SBR_HEADER_DATA hHdr2 ) +{ + int result = 0; + + /* compare basic data */ + result |= (hHdr1->syncState != hHdr2->syncState) ? 1 : 0; + result |= (hHdr1->status != hHdr2->status) ? 1 : 0; + result |= (hHdr1->frameErrorFlag != hHdr2->frameErrorFlag) ? 1 : 0; + result |= (hHdr1->numberTimeSlots != hHdr2->numberTimeSlots) ? 1 : 0; + result |= (hHdr1->numberOfAnalysisBands != hHdr2->numberOfAnalysisBands) ? 1 : 0; + result |= (hHdr1->timeStep != hHdr2->timeStep) ? 1 : 0; + result |= (hHdr1->sbrProcSmplRate != hHdr2->sbrProcSmplRate) ? 1 : 0; + + /* compare bitstream data */ + result |= FDKmemcmp( &hHdr1->bs_data, &hHdr2->bs_data, sizeof(SBR_HEADER_DATA_BS) ); + result |= FDKmemcmp( &hHdr1->bs_info, &hHdr2->bs_info, sizeof(SBR_HEADER_DATA_BS_INFO) ); + + /* compare frequency band data */ + result |= FDKmemcmp( &hHdr1->freqBandData, &hHdr2->freqBandData, (8+MAX_NUM_LIMITERS+1)*sizeof(UCHAR) ); + result |= FDKmemcmp( hHdr1->freqBandData.freqBandTableLo, hHdr2->freqBandData.freqBandTableLo, (MAX_FREQ_COEFFS/2+1)*sizeof(UCHAR) ); + result |= FDKmemcmp( hHdr1->freqBandData.freqBandTableHi, hHdr2->freqBandData.freqBandTableHi, (MAX_FREQ_COEFFS+1)*sizeof(UCHAR) ); + result |= FDKmemcmp( hHdr1->freqBandData.freqBandTableNoise, hHdr2->freqBandData.freqBandTableNoise, (MAX_NOISE_COEFFS+1)*sizeof(UCHAR) ); + result |= FDKmemcmp( hHdr1->freqBandData.v_k_master, hHdr2->freqBandData.v_k_master, (MAX_FREQ_COEFFS+1)*sizeof(UCHAR) ); + + return result; +} + /*! \brief Reset SBR decoder. @@ -391,6 +419,7 @@ int sbrDecoder_isCoreCodecValid(AUDIO_OBJECT_TYPE coreCodec) case AOT_PS: case AOT_ER_AAC_SCAL: case AOT_ER_AAC_ELD: + case AOT_DRM_AAC: return 1; default: return 0; @@ -463,6 +492,8 @@ SBR_ERROR sbrDecoder_InitElement ( self->flags = 0; self->flags |= (coreCodec == AOT_ER_AAC_ELD) ? SBRDEC_ELD_GRID : 0; + self->flags |= (coreCodec == AOT_ER_AAC_SCAL) ? SBRDEC_SYNTAX_SCAL : 0; + self->flags |= (coreCodec == AOT_DRM_AAC) ? SBRDEC_SYNTAX_SCAL|SBRDEC_SYNTAX_DRM : 0; /* Init SBR elements */ { @@ -928,24 +959,73 @@ SBR_ERROR sbrDecoder_Parse( ) { SBR_DECODER_ELEMENT *hSbrElement; - HANDLE_SBR_HEADER_DATA hSbrHeader; + HANDLE_SBR_HEADER_DATA hSbrHeader = NULL; HANDLE_SBR_CHANNEL *pSbrChannel; SBR_FRAME_DATA *hFrameDataLeft; SBR_FRAME_DATA *hFrameDataRight; SBR_ERROR errorStatus = SBRDEC_OK; - SBR_SYNC_STATE initialSyncState; SBR_HEADER_STATUS headerStatus = HEADER_NOT_PRESENT; INT startPos; INT CRCLen = 0; + HANDLE_FDK_BITSTREAM hBsOriginal = hBs; + FDK_CRCINFO crcInfo; /* shall be used for all other CRCs in the future (TBD) */ + INT crcReg = 0; + USHORT drmSbrCrc = 0; int stereo; int fDoDecodeSbrData = 1; int lastSlot, lastHdrSlot = 0, thisHdrSlot; + /* Reverse bits of DRM SBR payload */ + if ( (self->flags & SBRDEC_SYNTAX_DRM) && *count > 0 ) + { + UCHAR *bsBufferDrm = (UCHAR*)self->workBuffer1; + HANDLE_FDK_BITSTREAM hBsBwd = (HANDLE_FDK_BITSTREAM) (bsBufferDrm + (512)); + int dataBytes, dataBits; + + dataBits = *count; + + if (dataBits > ((512)*8)) { + /* do not flip more data than needed */ + dataBits = (512)*8; + } + + dataBytes = (dataBits+7)>>3; + + int j; + + if ((j = (int)FDKgetValidBits(hBs)) != 8) { + FDKpushBiDirectional(hBs, (j-8)); + } + + j = 0; + for ( ; dataBytes > 0; dataBytes--) + { + int i; + UCHAR tmpByte; + UCHAR buffer = 0x00; + + tmpByte = (UCHAR) FDKreadBits(hBs, 8); + for (i = 0; i < 4; i++) { + int shift = 2 * i + 1; + buffer |= (tmpByte & (0x08>>i)) << shift; + buffer |= (tmpByte & (0x10<> shift; + } + bsBufferDrm[j++] = buffer; + FDKpushBack(hBs, 16); + } + + FDKinitBitStream(hBsBwd, bsBufferDrm, (512), dataBits, BS_READER); + + /* Use reversed data */ + hBs = hBsBwd; + bsPayLen = *count; + } + /* Remember start position of SBR element */ startPos = FDKgetValidBits(hBs); @@ -970,7 +1050,6 @@ SBR_ERROR sbrDecoder_Parse( hFrameDataLeft = &self->pSbrElement[elementIndex]->pSbrChannel[0]->frameData[hSbrElement->useFrameSlot]; hFrameDataRight = &self->pSbrElement[elementIndex]->pSbrChannel[1]->frameData[hSbrElement->useFrameSlot]; - initialSyncState = hSbrHeader->syncState; /* reset PS flag; will be set after PS was found */ self->flags &= ~SBRDEC_PS_DECODED; @@ -1006,12 +1085,19 @@ SBR_ERROR sbrDecoder_Parse( */ if (fDoDecodeSbrData) { - if (crcFlag == 1) { + if (crcFlag) { switch (self->coreCodec) { case AOT_ER_AAC_ELD: FDKpushFor (hBs, 10); /* check sbrcrc later: we don't know the payload length now */ break; + case AOT_DRM_AAC: + drmSbrCrc = (USHORT)FDKreadBits(hBs, 8); + /* Setup CRC decoder */ + FDKcrcInit(&crcInfo, 0x001d, 0xFFFF, 8); + /* Start CRC region */ + crcReg = FDKcrcStartReg(&crcInfo, hBs, 0); + break; default: CRCLen = bsPayLen - 10; /* change: 0 => i */ if (CRCLen < 0) { @@ -1056,6 +1142,7 @@ SBR_ERROR sbrDecoder_Parse( hSbrHeader->syncState = SBR_HEADER; } else { hSbrHeader->syncState = SBR_NOT_INITIALIZED; + headerStatus = HEADER_ERROR; } } @@ -1105,7 +1192,7 @@ SBR_ERROR sbrDecoder_Parse( valBits = (INT)FDKgetValidBits(hBs); } - if ( crcFlag == 1 ) { + if ( crcFlag ) { switch (self->coreCodec) { case AOT_ER_AAC_ELD: { @@ -1117,6 +1204,14 @@ SBR_ERROR sbrDecoder_Parse( FDKpushFor(hBs, crcLen); } break; + case AOT_DRM_AAC: + /* End CRC region */ + FDKcrcEndReg(&crcInfo, hBs, crcReg); + /* Check CRC */ + if ((FDKcrcGetCRC(&crcInfo)^0xFF) != drmSbrCrc) { + fDoDecodeSbrData = 0; + } + break; default: break; } @@ -1167,8 +1262,25 @@ SBR_ERROR sbrDecoder_Parse( } bail: - if (errorStatus == SBRDEC_OK) { - if (headerStatus == HEADER_NOT_PRESENT) { + + if ( self->flags & SBRDEC_SYNTAX_DRM ) + { + hBs = hBsOriginal; + } + + if ( (errorStatus == SBRDEC_OK) + || ( (errorStatus == SBRDEC_PARSE_ERROR) + && (headerStatus != HEADER_ERROR) ) ) + { + int useOldHdr = ( (headerStatus == HEADER_NOT_PRESENT) + || (headerStatus == HEADER_ERROR) ) ? 1 : 0; + + if (!useOldHdr && (thisHdrSlot != lastHdrSlot)) { + useOldHdr |= ( compareSbrHeader( hSbrHeader, + &self->sbrHeader[elementIndex][lastHdrSlot] ) == 0 ) ? 1 : 0; + } + + if (useOldHdr != 0) { /* Use the old header for this frame */ hSbrElement->useHeaderSlot[hSbrElement->useFrameSlot] = lastHdrSlot; } else { @@ -1229,12 +1341,21 @@ sbrDecoder_DecodeElement ( 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]; + if ( self->numFlushedFrames > self->numDelayFrames ) { + int hdrIdx; + /* No valid SBR payload available, hence switch to upsampling (in all headers) */ + for (hdrIdx = 0; hdrIdx < ((1)+1); hdrIdx += 1) { + self->sbrHeader[elementIndex][hdrIdx].syncState = UPSAMPLING; + } + } + else { + /* 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 */ @@ -1354,7 +1475,8 @@ sbrDecoder_DecodeElement ( &pSbrChannel[0]->prevFrameData, (hSbrHeader->syncState == SBR_ACTIVE), h_ps_d, - self->flags + self->flags, + codecFrameSize ); if (stereo) { @@ -1371,7 +1493,8 @@ sbrDecoder_DecodeElement ( &pSbrChannel[1]->prevFrameData, (hSbrHeader->syncState == SBR_ACTIVE), NULL, - self->flags + self->flags, + codecFrameSize ); } @@ -1387,20 +1510,21 @@ sbrDecoder_DecodeElement ( if ( !(self->flags & SBRDEC_PS_DECODED) ) { /* A decoder which is able to decode PS has to produce a stereo output even if no PS data is availble. */ /* So copy left channel to right channel. */ + int copyFrameSize = codecFrameSize * 2 / self->synDownsampleFac; if (interleaved) { INT_PCM *ptr; INT i; FDK_ASSERT(strideOut == 2); ptr = timeData; - for (i = codecFrameSize; i--; ) + for (i = copyFrameSize>>1; i--; ) { INT_PCM tmp; /* This temporal variable is required because some compilers can't do *ptr++ = *ptr++ correctly. */ tmp = *ptr++; *ptr++ = tmp; tmp = *ptr++; *ptr++ = tmp; } } else { - FDKmemcpy( timeData+2*codecFrameSize, timeData, 2*codecFrameSize*sizeof(INT_PCM) ); + FDKmemcpy( timeData+copyFrameSize, timeData, copyFrameSize*sizeof(INT_PCM) ); } } *numOutChannels = 2; /* Output minimum two channels when PS is enabled. */ @@ -1464,14 +1588,23 @@ SBR_ERROR sbrDecoder_Apply ( HANDLE_SBRDECODER self, self->flags &= ~SBRDEC_PS_DECODED; } + if ( self->flags & SBRDEC_FLUSH ) { + /* flushing is signalized, hence increment the flush frame counter */ + self->numFlushedFrames++; + } + else { + /* no flushing is signalized, hence reset the flush frame counter */ + self->numFlushedFrames = 0; + } + /* Loop over SBR elements */ for (sbrElementNum = 0; sbrElementNumnumSbrElements; sbrElementNum++) { int numElementChan; if (psPossible && self->pSbrElement[sbrElementNum]->pSbrChannel[1] == NULL) { - errorStatus = SBRDEC_UNSUPPORTED_CONFIG; - goto bail; + /* Disable PS and try decoding SBR mono. */ + psPossible = 0; } numElementChan = (self->pSbrElement[sbrElementNum]->elementID == ID_CPE) ? 2 : 1; @@ -1579,6 +1712,7 @@ INT sbrDecoder_GetLibInfo( LIB_INFO *info ) | CAPF_SBR_HQ | CAPF_SBR_LP | CAPF_SBR_PS_MPEG + | CAPF_SBR_DRM_BS | CAPF_SBR_CONCEALMENT | CAPF_SBR_DRC ; @@ -1607,6 +1741,9 @@ UINT sbrDecoder_GetDelay( const HANDLE_SBRDECODER self ) /* Low delay SBR: */ { outputDelay += (flags & SBRDEC_DOWNSAMPLE) ? 32 : 64; /* QMF synthesis */ + if (flags & SBRDEC_LD_MPS_QMF) { + outputDelay += 32; + } } } else if (!IS_USAC(self->coreCodec)) { diff --git a/libSYS/src/genericStds.cpp b/libSYS/src/genericStds.cpp index 53abe06..89c422c 100644 --- a/libSYS/src/genericStds.cpp +++ b/libSYS/src/genericStds.cpp @@ -92,14 +92,14 @@ amm-info@iis.fraunhofer.de #define _CRT_SECURE_NO_WARNINGS -#include "genericStds.h" - #include +#include "genericStds.h" + /* library info */ #define SYS_LIB_VL0 1 #define SYS_LIB_VL1 3 -#define SYS_LIB_VL2 7 +#define SYS_LIB_VL2 8 #define SYS_LIB_TITLE "System Integration Library" #ifdef __ANDROID__ #define SYS_LIB_BUILD_DATE "" -- cgit v1.2.3