diff options
author | Fraunhofer IIS FDK <audio-fdk@iis.fraunhofer.de> | 2018-02-26 20:17:00 +0100 |
---|---|---|
committer | Jean-Michel Trivi <jmtrivi@google.com> | 2018-04-19 11:21:15 -0700 |
commit | 6cfabd35363c3ef5e3b209b867169a500b3ccc3c (patch) | |
tree | 01c0a19f2735e8b5d2407555fe992d4230d089eb /libAACdec/src/aacdec_drc.cpp | |
parent | 6288a1e34c4dede4c2806beb1736ece6580558c7 (diff) | |
download | fdk-aac-6cfabd35363c3ef5e3b209b867169a500b3ccc3c.tar.gz fdk-aac-6cfabd35363c3ef5e3b209b867169a500b3ccc3c.tar.bz2 fdk-aac-6cfabd35363c3ef5e3b209b867169a500b3ccc3c.zip |
Upgrade to FDKv2
Bug: 71430241
Test: CTS DecoderTest and DecoderTestAacDrc
original-Change-Id: Iaa20f749b8a04d553b20247cfe1a8930ebbabe30
Apply clang-format also on header files.
original-Change-Id: I14de1ef16bbc79ec0283e745f98356a10efeb2e4
Fixes for MPEG-D DRC
original-Change-Id: If1de2d74bbbac84b3f67de3b88b83f6a23b8a15c
Catch unsupported tw_mdct at an early stage
original-Change-Id: Ied9dd00d754162a0e3ca1ae3e6b854315d818afe
Fixing PVC transition frames
original-Change-Id: Ib75725abe39252806c32d71176308f2c03547a4e
Move qmf bands sanity check
original-Change-Id: Iab540c3013c174d9490d2ae100a4576f51d8dbc4
Initialize scaling variable
original-Change-Id: I3c4087101b70e998c71c1689b122b0d7762e0f9e
Add 16 qmf band configuration to getSlotNrgHQ()
original-Change-Id: I49a5d30f703a1b126ff163df9656db2540df21f1
Always apply byte alignment at the end of the AudioMuxElement
original-Change-Id: I42d560287506d65d4c3de8bfe3eb9a4ebeb4efc7
Setup SBR element only if no parse error exists
original-Change-Id: I1915b73704bc80ab882b9173d6bec59cbd073676
Additional array index check in HCR
original-Change-Id: I18cc6e501ea683b5009f1bbee26de8ddd04d8267
Fix fade-in index selection in concealment module
original-Change-Id: Ibf802ed6ed8c05e9257e1f3b6d0ac1162e9b81c1
Enable explicit backward compatible parser for AAC_LD
original-Change-Id: I27e9c678dcb5d40ed760a6d1e06609563d02482d
Skip spatial specific config in explicit backward compatible ASC
original-Change-Id: Iff7cc365561319e886090cedf30533f562ea4d6e
Update flags description in decoder API
original-Change-Id: I9a5b4f8da76bb652f5580cbd3ba9760425c43830
Add QMF domain reset function
original-Change-Id: I4f89a8a2c0277d18103380134e4ed86996e9d8d6
DRC upgrade v2.1.0
original-Change-Id: I5731c0540139dab220094cd978ef42099fc45b74
Fix integer overflow in sqrtFixp_lookup()
original-Change-Id: I429a6f0d19aa2cc957e0f181066f0ca73968c914
Fix integer overflow in invSqrtNorm2()
original-Change-Id: I84de5cbf9fb3adeb611db203fe492fabf4eb6155
Fix integer overflow in GenerateRandomVector()
original-Change-Id: I3118a641008bd9484d479e5b0b1ee2b5d7d44d74
Fix integer overflow in adjustTimeSlot_EldGrid()
original-Change-Id: I29d503c247c5c8282349b79df940416a512fb9d5
Fix integer overflow in FDKsbrEnc_codeEnvelope()
original-Change-Id: I6b34b61ebb9d525b0c651ed08de2befc1f801449
Follow-up on: Fix integer overflow in adjustTimeSlot_EldGrid()
original-Change-Id: I6f8f578cc7089e5eb7c7b93e580b72ca35ad689a
Fix integer overflow in get_pk_v2()
original-Change-Id: I63375bed40d45867f6eeaa72b20b1f33e815938c
Fix integer overflow in Syn_filt_zero()
original-Change-Id: Ie0c02fdfbe03988f9d3b20d10cd9fe4c002d1279
Fix integer overflow in CFac_CalcFacSignal()
original-Change-Id: Id2d767c40066c591b51768e978eb8af3b803f0c5
Fix integer overflow in FDKaacEnc_FDKaacEnc_calcPeNoAH()
original-Change-Id: Idcbd0f4a51ae2550ed106aa6f3d678d1f9724841
Fix integer overflow in sbrDecoder_calculateGainVec()
original-Change-Id: I7081bcbe29c5cede9821b38d93de07c7add2d507
Fix integer overflow in CLpc_SynthesisLattice()
original-Change-Id: I4a95ddc18de150102352d4a1845f06094764c881
Fix integer overflow in Pred_Lt4()
original-Change-Id: I4dbd012b2de7d07c3e70a47b92e3bfae8dbc750a
Fix integer overflow in FDKsbrEnc_InitSbrFastTransientDetector()
original-Change-Id: I788cbec1a4a00f44c2f3a72ad7a4afa219807d04
Fix unsigned integer overflow in FDKaacEnc_WriteBitstream()
original-Change-Id: I68fc75166e7d2cd5cd45b18dbe3d8c2a92f1822a
Fix unsigned integer overflow in FDK_MetadataEnc_Init()
original-Change-Id: Ie8d025f9bcdb2442c704bd196e61065c03c10af4
Fix overflow in pseudo random number generators
original-Change-Id: I3e2551ee01356297ca14e3788436ede80bd5513c
Fix unsigned integer overflow in sbrDecoder_Parse()
original-Change-Id: I3f231b2f437e9c37db4d5b964164686710eee971
Fix unsigned integer overflow in longsub()
original-Change-Id: I73c2bc50415cac26f1f5a29e125bbe75f9180a6e
Fix unsigned integer overflow in CAacDecoder_DecodeFrame()
original-Change-Id: Ifce2db4b1454b46fa5f887e9d383f1cc43b291e4
Fix overflow at CLpdChannelStream_Read()
original-Change-Id: Idb9d822ce3a4272e4794b643644f5434e2d4bf3f
Fix unsigned integer overflow in Hcr_State_BODY_SIGN_ESC__ESC_WORD()
original-Change-Id: I1ccf77c0015684b85534c5eb97162740a870b71c
Fix unsigned integer overflow in UsacConfig_Parse()
original-Change-Id: Ie6d27f84b6ae7eef092ecbff4447941c77864d9f
Fix unsigned integer overflow in aacDecoder_drcParse()
original-Change-Id: I713f28e883eea3d70b6fa56a7b8f8c22bcf66ca0
Fix unsigned integer overflow in aacDecoder_drcReadCompression()
original-Change-Id: Ia34dfeb88c4705c558bce34314f584965cafcf7a
Fix unsigned integer overflow in CDataStreamElement_Read()
original-Change-Id: Iae896cc1d11f0a893d21be6aa90bd3e60a2c25f0
Fix unsigned integer overflow in transportDec_AdjustEndOfAccessUnit()
original-Change-Id: I64cf29a153ee784bb4a16fdc088baabebc0007dc
Fix unsigned integer overflow in transportDec_GetAuBitsRemaining()
original-Change-Id: I975b3420faa9c16a041874ba0db82e92035962e4
Fix unsigned integer overflow in extractExtendedData()
original-Change-Id: I2a59eb09e2053cfb58dfb75fcecfad6b85a80a8f
Fix signed integer overflow in CAacDecoder_ExtPayloadParse()
original-Change-Id: I4ad5ca4e3b83b5d964f1c2f8c5e7b17c477c7929
Fix unsigned integer overflow in CAacDecoder_DecodeFrame()
original-Change-Id: I29a39df77d45c52a0c9c5c83c1ba81f8d0f25090
Follow-up on: Fix integer overflow in CLpc_SynthesisLattice()
original-Change-Id: I8fb194ffc073a3432a380845be71036a272d388f
Fix signed integer overflow in _interpolateDrcGain()
original-Change-Id: I879ec9ab14005069a7c47faf80e8bc6e03d22e60
Fix unsigned integer overflow in FDKreadBits()
original-Change-Id: I1f47a6a8037ff70375aa8844947d5681bb4287ad
Fix unsigned integer overflow in FDKbyteAlign()
original-Change-Id: Id5f3a11a0c9e50fc6f76ed6c572dbd4e9f2af766
Fix unsigned integer overflow in FDK_get32()
original-Change-Id: I9d33b8e97e3d38cbb80629cb859266ca0acdce96
Fix unsigned integer overflow in FDK_pushBack()
original-Change-Id: Ic87f899bc8c6acf7a377a8ca7f3ba74c3a1e1c19
Fix unsigned integer overflow in FDK_pushForward()
original-Change-Id: I3b754382f6776a34be1602e66694ede8e0b8effc
Fix unsigned integer overflow in ReadPsData()
original-Change-Id: I25361664ba8139e32bbbef2ca8c106a606ce9c37
Fix signed integer overflow in E_UTIL_residu()
original-Change-Id: I8c3abd1f437ee869caa8fb5903ce7d3d641b6aad
REVERT: Follow-up on: Integer overflow in CLpc_SynthesisLattice().
original-Change-Id: I3d340099acb0414795c8dfbe6362bc0a8f045f9b
Follow-up on: Fix integer overflow in CLpc_SynthesisLattice()
original-Change-Id: I4aedb8b3a187064e9f4d985175aa55bb99cc7590
Follow-up on: Fix unsigned integer overflow in aacDecoder_drcParse()
original-Change-Id: I2aa2e13916213bf52a67e8b0518e7bf7e57fb37d
Fix integer overflow in acelp
original-Change-Id: Ie6390c136d84055f8b728aefbe4ebef6e029dc77
Fix unsigned integer overflow in aacDecoder_UpdateBitStreamCounters()
original-Change-Id: I391ffd97ddb0b2c184cba76139bfb356a3b4d2e2
Adjust concealment default settings
original-Change-Id: I6a95db935a327c47df348030bcceafcb29f54b21
Saturate estimatedStartPos
original-Change-Id: I27be2085e0ae83ec9501409f65e003f6bcba1ab6
Negative shift exponent in _interpolateDrcGain()
original-Change-Id: I18edb26b26d002aafd5e633d4914960f7a359c29
Negative shift exponent in calculateICC()
original-Change-Id: I3dcd2ae98d2eb70ee0d59750863cbb2a6f4f8aba
Too large shift exponent in FDK_put()
original-Change-Id: Ib7d9aaa434d2d8de4a13b720ca0464b31ca9b671
Too large shift exponent in CalcInvLdData()
original-Change-Id: I43e6e78d4cd12daeb1dcd5d82d1798bdc2550262
Member access within null pointer of type SBR_CHANNEL
original-Change-Id: Idc5e4ea8997810376d2f36bbdf628923b135b097
Member access within null pointer of type CpePersistentData
original-Change-Id: Ib6c91cb0d37882768e5baf63324e429589de0d9d
Member access within null pointer FDKaacEnc_psyMain()
original-Change-Id: I7729b7f4479970531d9dc823abff63ca52e01997
Member access within null pointer FDKaacEnc_GetPnsParam()
original-Change-Id: I9aa3b9f3456ae2e0f7483dbd5b3dde95fc62da39
Member access within null pointer FDKsbrEnc_EnvEncodeFrame()
original-Change-Id: I67936f90ea714e90b3e81bc0dd1472cc713eb23a
Add HCR sanity check
original-Change-Id: I6c1d9732ebcf6af12f50b7641400752f74be39f7
Fix memory issue for HBE edge case with 8:3 SBR
original-Change-Id: I11ea58a61e69fbe8bf75034b640baee3011e63e9
Additional SBR parametrization sanity check for ELD
original-Change-Id: Ie26026fbfe174c2c7b3691f6218b5ce63e322140
Add MPEG-D DRC channel layout check
original-Change-Id: Iea70a74f171b227cce636a9eac4ba662777a2f72
Additional out-of-bounds checks in MPEG-D DRC
original-Change-Id: Ife4a8c3452c6fde8a0a09e941154a39a769777d4
Change-Id: Ic63cb2f628720f54fe9b572b0cb528e2599c624e
Diffstat (limited to 'libAACdec/src/aacdec_drc.cpp')
-rw-r--r-- | libAACdec/src/aacdec_drc.cpp | 1389 |
1 files changed, 778 insertions, 611 deletions
diff --git a/libAACdec/src/aacdec_drc.cpp b/libAACdec/src/aacdec_drc.cpp index eb8e410..922a09e 100644 --- a/libAACdec/src/aacdec_drc.cpp +++ b/libAACdec/src/aacdec_drc.cpp @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. - All rights reserved. +© Copyright 1995 - 2018 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. +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: +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 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 +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. +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. +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." +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. +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. +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. +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 @@ -79,37 +90,64 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ -/***************************** MPEG-4 AAC Decoder ************************** +/**************************** AAC decoder library ****************************** Author(s): Christian Griebel + Description: Dynamic range control (DRC) decoder tool for AAC -******************************************************************************/ +*******************************************************************************/ #include "aacdec_drc.h" - #include "channelinfo.h" #include "aac_rom.h" - #include "sbrdecoder.h" +#include "sbrdecoder.h" /* * Dynamic Range Control */ /* For parameter conversion */ -#define DRC_PARAMETER_BITS ( 7 ) -#define DRC_MAX_QUANT_STEPS ( 1<<DRC_PARAMETER_BITS ) -#define DRC_MAX_QUANT_FACTOR ( DRC_MAX_QUANT_STEPS-1 ) -#define DRC_PARAM_QUANT_STEP ( FL2FXCONST_DBL(1.0f/(float)DRC_MAX_QUANT_FACTOR) ) -#define DRC_PARAM_SCALE ( 1 ) +#define DRC_PARAMETER_BITS (7) +#define DRC_MAX_QUANT_STEPS (1 << DRC_PARAMETER_BITS) +#define DRC_MAX_QUANT_FACTOR (DRC_MAX_QUANT_STEPS - 1) +#define DRC_PARAM_QUANT_STEP \ + (FL2FXCONST_DBL(1.0f / (float)DRC_MAX_QUANT_FACTOR)) +#define DRC_PARAM_SCALE (1) +#define DRC_SCALING_MAX \ + ((FIXP_DBL)((INT)(DRC_PARAM_QUANT_STEP >> DRC_PARAM_SCALE) * (INT)127)) + +#define DRC_BLOCK_LEN (1024) +#define DRC_BAND_MULT (4) +#define DRC_BLOCK_LEN_DIV_BAND_MULT (DRC_BLOCK_LEN / DRC_BAND_MULT) + +#define MAX_REFERENCE_LEVEL (127) + +#define DRC_HEAVY_THRESHOLD_DB (10) + +#define DVB_ANC_DATA_SYNC_BYTE (0xBC) /* DVB ancillary data sync byte. */ -#define MAX_REFERENCE_LEVEL ( 127 ) +#define OFF 0 +#define ON 1 - #define DVB_ANC_DATA_SYNC_BYTE ( 0xBC ) /* DVB ancillary data sync byte. */ +static INT convert_drcParam(FIXP_DBL param_dbl) { + /* converts an internal DRC boost/cut scaling factor in FIXP_DBL + (which is downscaled by DRC_PARAM_SCALE) + back to an integer value between 0 and 127. */ + LONG param_long; + + param_long = (LONG)param_dbl >> 7; + param_long = param_long * (INT)DRC_MAX_QUANT_FACTOR; + param_long >>= 31 - 7 - DRC_PARAM_SCALE - 1; + param_long += 1; /* for rounding */ + param_long >>= 1; + + return (INT)param_long; +} /*! \brief Initialize DRC information @@ -118,9 +156,7 @@ amm-info@iis.fraunhofer.de \return none */ -void aacDecoder_drcInit ( - HANDLE_AAC_DRC self ) -{ +void aacDecoder_drcInit(HANDLE_AAC_DRC self) { CDrcParams *pParams; if (self == NULL) { @@ -128,28 +164,36 @@ void aacDecoder_drcInit ( } /* init control fields */ - self->enable = 0; + self->enable = OFF; self->numThreads = 0; /* init params */ pParams = &self->params; pParams->bsDelayEnable = 0; - pParams->cut = FL2FXCONST_DBL(0.0f); - pParams->usrCut = FL2FXCONST_DBL(0.0f); - pParams->boost = FL2FXCONST_DBL(0.0f); + pParams->cut = FL2FXCONST_DBL(0.0f); + pParams->usrCut = FL2FXCONST_DBL(0.0f); + pParams->boost = FL2FXCONST_DBL(0.0f); pParams->usrBoost = FL2FXCONST_DBL(0.0f); pParams->targetRefLevel = -1; pParams->expiryFrame = AACDEC_DRC_DFLT_EXPIRY_FRAMES; - pParams->applyDigitalNorm = 0; - pParams->applyHeavyCompression = 0; + pParams->applyDigitalNorm = OFF; + pParams->applyHeavyCompression = OFF; + pParams->usrApplyHeavyCompression = OFF; + + pParams->defaultPresentationMode = DISABLED_PARAMETER_HANDLING; + pParams->encoderTargetLevel = MAX_REFERENCE_LEVEL; /* worst case assumption */ + + self->update = 1; + self->numOutChannels = 0; + self->prevAacNumChannels = 0; /* initial program ref level = target ref level */ self->progRefLevel = pParams->targetRefLevel; self->progRefLevelPresent = 0; self->presMode = -1; + self->uniDrcPrecedence = 0; } - /*! \brief Initialize DRC control data for one channel @@ -157,20 +201,17 @@ void aacDecoder_drcInit ( \return none */ -void aacDecoder_drcInitChannelData ( - CDrcChannelData *pDrcChData ) -{ +void aacDecoder_drcInitChannelData(CDrcChannelData *pDrcChData) { if (pDrcChData != NULL) { pDrcChData->expiryCount = 0; - pDrcChData->numBands = 1; - pDrcChData->bandTop[0] = (1024 >> 2) - 1; + pDrcChData->numBands = 1; + pDrcChData->bandTop[0] = DRC_BLOCK_LEN_DIV_BAND_MULT - 1; pDrcChData->drcValue[0] = 0; pDrcChData->drcInterpolationScheme = 0; pDrcChData->drcDataType = UNKNOWN_PAYLOAD; } } - /*! \brief Set one single DRC parameter @@ -180,141 +221,152 @@ void aacDecoder_drcInitChannelData ( \return an error code. */ -AAC_DECODER_ERROR aacDecoder_drcSetParam ( - HANDLE_AAC_DRC self, - AACDEC_DRC_PARAM param, - INT value ) -{ +AAC_DECODER_ERROR aacDecoder_drcSetParam(HANDLE_AAC_DRC self, + AACDEC_DRC_PARAM param, INT value) { AAC_DECODER_ERROR ErrorStatus = AAC_DEC_OK; - switch (param) - { - case DRC_CUT_SCALE: - /* set attenuation scale factor */ - if ( (value < 0) - || (value > DRC_MAX_QUANT_FACTOR) ) { - return AAC_DEC_SET_PARAM_FAIL; - } - if (self == NULL) { - return AAC_DEC_INVALID_HANDLE; - } - self->params.usrCut = (FIXP_DBL)((INT)(DRC_PARAM_QUANT_STEP>>DRC_PARAM_SCALE) * (INT)value); - if (self->params.applyHeavyCompression == 0) - self->params.cut = self->params.usrCut; - break; - case DRC_BOOST_SCALE: - /* set boost factor */ - if ( (value < 0) - || (value > DRC_MAX_QUANT_FACTOR) ) { - return AAC_DEC_SET_PARAM_FAIL; - } - if (self == NULL) { - return AAC_DEC_INVALID_HANDLE; - } - self->params.usrBoost = (FIXP_DBL)((INT)(DRC_PARAM_QUANT_STEP>>DRC_PARAM_SCALE) * (INT)value); - if (self->params.applyHeavyCompression == 0) - self->params.boost = self->params.usrBoost; - break; - case TARGET_REF_LEVEL: - if ( value > MAX_REFERENCE_LEVEL - || value < -MAX_REFERENCE_LEVEL ) { - return AAC_DEC_SET_PARAM_FAIL; - } - if (self == NULL) { - return AAC_DEC_INVALID_HANDLE; - } - if (value < 0) { - self->params.applyDigitalNorm = 0; - self->params.targetRefLevel = -1; - } - else { - /* ref_level must be between 0 and MAX_REFERENCE_LEVEL, inclusive */ - self->params.applyDigitalNorm = 1; - if (self->params.targetRefLevel != (SCHAR)value) { - self->params.targetRefLevel = (SCHAR)value; - self->progRefLevel = (SCHAR)value; /* Always set the program reference level equal to the - target level according to 4.5.2.7.3 of ISO/IEC 14496-3. */ + switch (param) { + case DRC_CUT_SCALE: + /* set attenuation scale factor */ + if ((value < 0) || (value > DRC_MAX_QUANT_FACTOR)) { + return AAC_DEC_SET_PARAM_FAIL; } - } - break; - case APPLY_NORMALIZATION: - if (value < 0 || value > 1) { - return AAC_DEC_SET_PARAM_FAIL; - } - if (self == NULL) { - return AAC_DEC_INVALID_HANDLE; - } - /* Store new parameter value */ - self->params.applyDigitalNorm = (UCHAR)value; - break; - case APPLY_HEAVY_COMPRESSION: - if (value < 0 || value > 1) { - return AAC_DEC_SET_PARAM_FAIL; - } - if (self == NULL) { - return AAC_DEC_INVALID_HANDLE; - } - if (self->params.applyHeavyCompression != (UCHAR)value) { - if (value == 1) { - /* Disable scaling of DRC values by setting the max values */ - self->params.boost = FL2FXCONST_DBL(1.0f/(float)(1<<DRC_PARAM_SCALE)); - self->params.cut = FL2FXCONST_DBL(1.0f/(float)(1<<DRC_PARAM_SCALE)); + if (self == NULL) { + return AAC_DEC_INVALID_HANDLE; + } + self->params.usrCut = (FIXP_DBL)( + (INT)(DRC_PARAM_QUANT_STEP >> DRC_PARAM_SCALE) * (INT)value); + self->update = 1; + break; + case DRC_BOOST_SCALE: + /* set boost factor */ + if ((value < 0) || (value > DRC_MAX_QUANT_FACTOR)) { + return AAC_DEC_SET_PARAM_FAIL; + } + if (self == NULL) { + return AAC_DEC_INVALID_HANDLE; + } + self->params.usrBoost = (FIXP_DBL)( + (INT)(DRC_PARAM_QUANT_STEP >> DRC_PARAM_SCALE) * (INT)value); + self->update = 1; + break; + case TARGET_REF_LEVEL: + if (value > MAX_REFERENCE_LEVEL || value < -MAX_REFERENCE_LEVEL) { + return AAC_DEC_SET_PARAM_FAIL; + } + if (self == NULL) { + return AAC_DEC_INVALID_HANDLE; + } + if (value < 0) { + self->params.applyDigitalNorm = OFF; + self->params.targetRefLevel = -1; } else { - /* Restore the user params */ - self->params.boost = self->params.usrBoost; - self->params.cut = self->params.usrCut; + /* ref_level must be between 0 and MAX_REFERENCE_LEVEL, inclusive */ + self->params.applyDigitalNorm = ON; + if (self->params.targetRefLevel != (SCHAR)value) { + self->params.targetRefLevel = (SCHAR)value; + self->progRefLevel = (SCHAR)value; /* Always set the program reference + level equal to the target level + according to 4.5.2.7.3 of + ISO/IEC 14496-3. */ + } + self->update = 1; + } + break; + case APPLY_NORMALIZATION: + if ((value != OFF) && (value != ON)) { + return AAC_DEC_SET_PARAM_FAIL; + } + if (self == NULL) { + return AAC_DEC_INVALID_HANDLE; } /* Store new parameter value */ - self->params.applyHeavyCompression = (UCHAR)value; - } - break; - case DRC_BS_DELAY: - if (value < 0 || value > 1) { + self->params.applyDigitalNorm = (UCHAR)value; + break; + case APPLY_HEAVY_COMPRESSION: + if ((value != OFF) && (value != ON)) { + return AAC_DEC_SET_PARAM_FAIL; + } + if (self == NULL) { + return AAC_DEC_INVALID_HANDLE; + } + /* Store new parameter value */ + self->params.usrApplyHeavyCompression = (UCHAR)value; + self->update = 1; + break; + case DEFAULT_PRESENTATION_MODE: + if (value < AAC_DRC_PARAMETER_HANDLING_DISABLED || + value > AAC_DRC_PRESENTATION_MODE_2_DEFAULT) { + return AAC_DEC_SET_PARAM_FAIL; + } + if (self == NULL) { + return AAC_DEC_INVALID_HANDLE; + } + self->params.defaultPresentationMode = + (AACDEC_DRC_PARAMETER_HANDLING)value; + self->update = 1; + break; + case ENCODER_TARGET_LEVEL: + if (value > MAX_REFERENCE_LEVEL || value < 0) { + return AAC_DEC_SET_PARAM_FAIL; + } + if (self == NULL) { + return AAC_DEC_INVALID_HANDLE; + } + self->params.encoderTargetLevel = (UCHAR)value; + self->update = 1; + break; + case DRC_BS_DELAY: + if (value < 0 || value > 1) { + return AAC_DEC_SET_PARAM_FAIL; + } + if (self == NULL) { + return AAC_DEC_INVALID_HANDLE; + } + self->params.bsDelayEnable = value; + break; + case DRC_DATA_EXPIRY_FRAME: + if (self == NULL) { + return AAC_DEC_INVALID_HANDLE; + } + self->params.expiryFrame = (value > 0) ? (UINT)value : 0; + break; + case MAX_OUTPUT_CHANNELS: + if (self == NULL) { + return AAC_DEC_INVALID_HANDLE; + } + self->numOutChannels = (INT)value; + self->update = 1; + break; + case UNIDRC_PRECEDENCE: + if (self == NULL) { + return AAC_DEC_INVALID_HANDLE; + } + self->uniDrcPrecedence = (UCHAR)value; + break; + default: return AAC_DEC_SET_PARAM_FAIL; - } - if (self == NULL) { - return AAC_DEC_INVALID_HANDLE; - } - self->params.bsDelayEnable = value; - break; - case DRC_DATA_EXPIRY_FRAME: - if (self == NULL) { - return AAC_DEC_INVALID_HANDLE; - } - self->params.expiryFrame = (UINT)value; - break; - default: - return AAC_DEC_SET_PARAM_FAIL; - } /* switch(param) */ - - /* switch on/off processing */ - self->enable = ( (self->params.boost > (FIXP_DBL)0) - || (self->params.cut > (FIXP_DBL)0) - || (self->params.applyHeavyCompression != 0) - || (self->params.targetRefLevel >= 0) ); - + } /* switch(param) */ return ErrorStatus; } - -static int parseExcludedChannels( UINT *excludedChnsMask, - HANDLE_FDK_BITSTREAM bs ) -{ +static int parseExcludedChannels(UINT *excludedChnsMask, + HANDLE_FDK_BITSTREAM bs) { UINT excludeMask = 0; UINT i, j; - int bitCnt = 9; + int bitCnt = 9; - for (i = 0, j = 1; i < 7; i++, j<<=1) { - if (FDKreadBits(bs,1)) { + for (i = 0, j = 1; i < 7; i++, j <<= 1) { + if (FDKreadBits(bs, 1)) { excludeMask |= j; } } /* additional_excluded_chns */ - while (FDKreadBits(bs,1)) { - for (i = 0; i < 7; i++, j<<=1) { - if (FDKreadBits(bs,1)) { + while (FDKreadBits(bs, 1)) { + for (i = 0; i < 7; i++, j <<= 1) { + if (FDKreadBits(bs, 1)) { excludeMask |= j; } } @@ -327,7 +379,6 @@ static int parseExcludedChannels( UINT *excludedChnsMask, return (bitCnt); } - /*! \brief Save DRC payload bitstream position @@ -336,13 +387,10 @@ static int parseExcludedChannels( UINT *excludedChnsMask, \return The number of DRC payload bits */ -int aacDecoder_drcMarkPayload ( - HANDLE_AAC_DRC self, - HANDLE_FDK_BITSTREAM bs, - AACDEC_DRC_PAYLOAD_TYPE type ) -{ +int aacDecoder_drcMarkPayload(HANDLE_AAC_DRC self, HANDLE_FDK_BITSTREAM bs, + AACDEC_DRC_PAYLOAD_TYPE type) { UINT bsStartPos; - int i, numBands = 1, bitCnt = 0; + int i, numBands = 1, bitCnt = 0; if (self == NULL) { return 0; @@ -351,97 +399,97 @@ int aacDecoder_drcMarkPayload ( bsStartPos = FDKgetValidBits(bs); switch (type) { - case MPEG_DRC_EXT_DATA: - { + case MPEG_DRC_EXT_DATA: { bitCnt = 4; - if (FDKreadBits(bs,1)) { /* pce_tag_present */ - FDKreadBits(bs,8); /* pce_instance_tag + drc_tag_reserved_bits */ - bitCnt+=8; + if (FDKreadBits(bs, 1)) { /* pce_tag_present */ + FDKreadBits(bs, 8); /* pce_instance_tag + drc_tag_reserved_bits */ + bitCnt += 8; } - if (FDKreadBits(bs,1)) { /* excluded_chns_present */ - FDKreadBits(bs,7); /* exclude mask [0..7] */ - bitCnt+=8; - while (FDKreadBits(bs,1)) { /* additional_excluded_chns */ - FDKreadBits(bs,7); /* exclude mask [x..y] */ - bitCnt+=8; + if (FDKreadBits(bs, 1)) { /* excluded_chns_present */ + FDKreadBits(bs, 7); /* exclude mask [0..7] */ + bitCnt += 8; + while (FDKreadBits(bs, 1)) { /* additional_excluded_chns */ + FDKreadBits(bs, 7); /* exclude mask [x..y] */ + bitCnt += 8; } } - if (FDKreadBits(bs,1)) { /* drc_bands_present */ + if (FDKreadBits(bs, 1)) { /* drc_bands_present */ numBands += FDKreadBits(bs, 4); /* drc_band_incr */ - FDKreadBits(bs,4); /* reserved */ - bitCnt+=8; + FDKreadBits(bs, 4); /* reserved */ + bitCnt += 8; for (i = 0; i < numBands; i++) { - FDKreadBits(bs,8); /* drc_band_top[i] */ - bitCnt+=8; + FDKreadBits(bs, 8); /* drc_band_top[i] */ + bitCnt += 8; } } - if (FDKreadBits(bs,1)) { /* prog_ref_level_present */ - FDKreadBits(bs,8); /* prog_ref_level + prog_ref_level_reserved_bits */ - bitCnt+=8; + if (FDKreadBits(bs, 1)) { /* prog_ref_level_present */ + FDKreadBits(bs, 8); /* prog_ref_level + prog_ref_level_reserved_bits */ + bitCnt += 8; } for (i = 0; i < numBands; i++) { - FDKreadBits(bs,8); /* dyn_rng_sgn[i] + dyn_rng_ctl[i] */ - bitCnt+=8; + FDKreadBits(bs, 8); /* dyn_rng_sgn[i] + dyn_rng_ctl[i] */ + bitCnt += 8; } - if ( (self->numPayloads < MAX_DRC_THREADS) - && ((INT)FDKgetValidBits(bs) >= 0) ) - { + if ((self->numPayloads < MAX_DRC_THREADS) && + ((INT)FDKgetValidBits(bs) >= 0)) { self->drcPayloadPosition[self->numPayloads++] = bsStartPos; } - } - break; + } break; case DVB_DRC_ANC_DATA: bitCnt += 8; /* check sync word */ - if (FDKreadBits(bs, 8) == DVB_ANC_DATA_SYNC_BYTE) - { + if (FDKreadBits(bs, 8) == DVB_ANC_DATA_SYNC_BYTE) { int dmxLevelsPresent, compressionPresent; int coarseGrainTcPresent, fineGrainTcPresent; - /* bs_info field */ - FDKreadBits(bs, 8); /* mpeg_audio_type, dolby_surround_mode, presentation_mode */ - bitCnt+=8; + /* bs_info field */ + FDKreadBits( + bs, + 8); /* mpeg_audio_type, dolby_surround_mode, presentation_mode */ + bitCnt += 8; /* Evaluate ancillary_data_status */ - FDKreadBits(bs, 3); /* reserved, set to 0 */ - dmxLevelsPresent = FDKreadBits(bs, 1); /* downmixing_levels_MPEG4_status */ - FDKreadBits(bs, 1); /* reserved, set to 0 */ - compressionPresent = FDKreadBits(bs, 1); /* audio_coding_mode_and_compression status */ - coarseGrainTcPresent = FDKreadBits(bs, 1); /* coarse_grain_timecode_status */ - fineGrainTcPresent = FDKreadBits(bs, 1); /* fine_grain_timecode_status */ - bitCnt+=8; + FDKreadBits(bs, 3); /* reserved, set to 0 */ + dmxLevelsPresent = + FDKreadBits(bs, 1); /* downmixing_levels_MPEG4_status */ + FDKreadBits(bs, 1); /* reserved, set to 0 */ + compressionPresent = + FDKreadBits(bs, 1); /* audio_coding_mode_and_compression status */ + coarseGrainTcPresent = + FDKreadBits(bs, 1); /* coarse_grain_timecode_status */ + fineGrainTcPresent = + FDKreadBits(bs, 1); /* fine_grain_timecode_status */ + bitCnt += 8; /* MPEG4 downmixing levels */ if (dmxLevelsPresent) { - FDKreadBits(bs, 8); /* downmixing_levels_MPEG4 */ - bitCnt+=8; + FDKreadBits(bs, 8); /* downmixing_levels_MPEG4 */ + bitCnt += 8; } /* audio coding mode and compression status */ if (compressionPresent) { - FDKreadBits(bs, 16); /* audio_coding_mode, Compression_value */ - bitCnt+=16; + FDKreadBits(bs, 16); /* audio_coding_mode, Compression_value */ + bitCnt += 16; } /* coarse grain timecode */ if (coarseGrainTcPresent) { - FDKreadBits(bs, 16); /* coarse_grain_timecode */ - bitCnt+=16; + FDKreadBits(bs, 16); /* coarse_grain_timecode */ + bitCnt += 16; } /* fine grain timecode */ if (fineGrainTcPresent) { - FDKreadBits(bs, 16); /* fine_grain_timecode */ - bitCnt+=16; + FDKreadBits(bs, 16); /* fine_grain_timecode */ + bitCnt += 16; } - if ( !self->dvbAncDataAvailable - && ((INT)FDKgetValidBits(bs) >= 0) ) - { - self->dvbAncDataPosition = bsStartPos; + if (!self->dvbAncDataAvailable && ((INT)FDKgetValidBits(bs) >= 0)) { + self->dvbAncDataPosition = bsStartPos; self->dvbAncDataAvailable = 1; } } @@ -454,112 +502,101 @@ int aacDecoder_drcMarkPayload ( return (bitCnt); } - /*! \brief Parse DRC parameters from bitstream \bs Handle of FDK bitstream (in) \pDrcBs Pointer to DRC payload data container (out) - \payloadPosition Bitstream position of MPEG DRC data junk (in) + \payloadPosition Bitstream position of MPEG DRC data chunk (in) - \return Number of bits read (0 in case of a parse error) + \return Flag telling whether new DRC data has been found or not. */ -static int aacDecoder_drcParse ( - HANDLE_FDK_BITSTREAM bs, - CDrcPayload *pDrcBs, - UINT payloadPosition ) -{ - int i, numBands, bitCnt = 4; +static int aacDecoder_drcParse(HANDLE_FDK_BITSTREAM bs, CDrcPayload *pDrcBs, + UINT payloadPosition) { + int i, numBands; /* Move to the beginning of the DRC payload field */ - FDKpushBiDirectional(bs, FDKgetValidBits(bs)-payloadPosition); + FDKpushBiDirectional(bs, (INT)FDKgetValidBits(bs) - (INT)payloadPosition); /* pce_tag_present */ - if (FDKreadBits(bs,1)) - { - pDrcBs->pceInstanceTag = FDKreadBits(bs, 4); /* pce_instance_tag */ + if (FDKreadBits(bs, 1)) { + pDrcBs->pceInstanceTag = FDKreadBits(bs, 4); /* pce_instance_tag */ /* only one program supported */ - FDKreadBits(bs, 4); /* drc_tag_reserved_bits */ - bitCnt += 8; + FDKreadBits(bs, 4); /* drc_tag_reserved_bits */ } else { - pDrcBs->pceInstanceTag = -1; /* not present */ + pDrcBs->pceInstanceTag = -1; /* not present */ } - if (FDKreadBits(bs,1)) { /* excluded_chns_present */ + if (FDKreadBits(bs, 1)) { /* excluded_chns_present */ /* get excluded_chn_mask */ - bitCnt += parseExcludedChannels(&pDrcBs->excludedChnsMask, bs); + parseExcludedChannels(&pDrcBs->excludedChnsMask, bs); } else { pDrcBs->excludedChnsMask = 0; } numBands = 1; - if (FDKreadBits(bs,1)) /* drc_bands_present */ + if (FDKreadBits(bs, 1)) /* drc_bands_present */ { /* get band_incr */ - numBands += FDKreadBits(bs, 4); /* drc_band_incr */ - pDrcBs->channelData.drcInterpolationScheme = FDKreadBits(bs, 4); /* drc_interpolation_scheme */ - bitCnt += 8; + numBands += FDKreadBits(bs, 4); /* drc_band_incr */ + pDrcBs->channelData.drcInterpolationScheme = + FDKreadBits(bs, 4); /* drc_interpolation_scheme */ /* band_top */ - for (i = 0; i < numBands; i++) - { - pDrcBs->channelData.bandTop[i] = FDKreadBits(bs, 8); /* drc_band_top[i] */ - bitCnt += 8; + for (i = 0; i < numBands; i++) { + pDrcBs->channelData.bandTop[i] = FDKreadBits(bs, 8); /* drc_band_top[i] */ } - } - else { - pDrcBs->channelData.bandTop[0] = (1024 >> 2) - 1; /* ... comprising the whole spectrum. */; + } else { + pDrcBs->channelData.bandTop[0] = DRC_BLOCK_LEN_DIV_BAND_MULT - + 1; /* ... comprising the whole spectrum. */ + ; } pDrcBs->channelData.numBands = numBands; - if (FDKreadBits(bs,1)) /* prog_ref_level_present */ + if (FDKreadBits(bs, 1)) /* prog_ref_level_present */ { - pDrcBs->progRefLevel = FDKreadBits(bs, 7); /* prog_ref_level */ - FDKreadBits(bs, 1); /* prog_ref_level_reserved_bits */ - bitCnt += 8; + pDrcBs->progRefLevel = FDKreadBits(bs, 7); /* prog_ref_level */ + FDKreadBits(bs, 1); /* prog_ref_level_reserved_bits */ } else { pDrcBs->progRefLevel = -1; } - for (i = 0; i < numBands; i++) - { - pDrcBs->channelData.drcValue[i] = FDKreadBits(bs, 1) << 7; /* dyn_rng_sgn[i] */ - pDrcBs->channelData.drcValue[i] |= FDKreadBits(bs, 7) & 0x7F; /* dyn_rng_ctl[i] */ - bitCnt += 8; + for (i = 0; i < numBands; i++) { + pDrcBs->channelData.drcValue[i] = FDKreadBits(bs, 1) + << 7; /* dyn_rng_sgn[i] */ + pDrcBs->channelData.drcValue[i] |= + FDKreadBits(bs, 7) & 0x7F; /* dyn_rng_ctl[i] */ } /* Set DRC payload type */ pDrcBs->channelData.drcDataType = MPEG_DRC_EXT_DATA; - return (bitCnt); + return (1); } - /*! - \brief Parse heavy compression value transported in DSEs of DVB streams with MPEG-4 content. + \brief Parse heavy compression value transported in DSEs of DVB streams with + MPEG-4 content. \bs Handle of FDK bitstream (in) \pDrcBs Pointer to DRC payload data container (out) - \payloadPosition Bitstream position of DVB ancillary data junk + \payloadPosition Bitstream position of DVB ancillary data chunk - \return Number of bits read (0 in case of a parse error) + \return Flag telling whether new DRC data has been found or not. */ -#define DVB_COMPRESSION_SCALE ( 8 ) /* 48,164 dB */ +#define DVB_COMPRESSION_SCALE (8) /* 48,164 dB */ -static int aacDecoder_drcReadCompression ( - HANDLE_FDK_BITSTREAM bs, - CDrcPayload *pDrcBs, - UINT payloadPosition ) -{ - int bitCnt = 0; - int dmxLevelsPresent, extensionPresent, compressionPresent; - int coarseGrainTcPresent, fineGrainTcPresent; +static int aacDecoder_drcReadCompression(HANDLE_FDK_BITSTREAM bs, + CDrcPayload *pDrcBs, + UINT payloadPosition) { + int foundDrcData = 0; + int dmxLevelsPresent, compressionPresent; /* Move to the beginning of the DRC payload field */ - FDKpushBiDirectional(bs, FDKgetValidBits(bs)-payloadPosition); + FDKpushBiDirectional(bs, (INT)FDKgetValidBits(bs) - (INT)payloadPosition); /* Sanity checks */ - if ( FDKgetValidBits(bs) < 24 ) { + if (FDKgetValidBits(bs) < 24) { return 0; } @@ -568,115 +605,87 @@ static int aacDecoder_drcReadCompression ( return 0; } - /* Evaluate bs_info field */ - if (FDKreadBits(bs, 2) != 3) { /* mpeg_audio_type */ + /* Evaluate bs_info field */ + if (FDKreadBits(bs, 2) != 3) { /* mpeg_audio_type */ /* No MPEG-4 audio data */ return 0; } - FDKreadBits(bs, 2); /* dolby_surround_mode */ - pDrcBs->presMode = FDKreadBits(bs, 2); /* presentation_mode */ - FDKreadBits(bs, 1); /* stereo_downmix_mode */ - if (FDKreadBits(bs, 1) != 0) { /* reserved, set to 0 */ + FDKreadBits(bs, 2); /* dolby_surround_mode */ + pDrcBs->presMode = FDKreadBits(bs, 2); /* presentation_mode */ + FDKreadBits(bs, 1); /* stereo_downmix_mode */ + if (FDKreadBits(bs, 1) != 0) { /* reserved, set to 0 */ return 0; } /* Evaluate ancillary_data_status */ - if (FDKreadBits(bs, 3) != 0) { /* reserved, set to 0 */ + if (FDKreadBits(bs, 3) != 0) { /* reserved, set to 0 */ return 0; } - dmxLevelsPresent = FDKreadBits(bs, 1); /* downmixing_levels_MPEG4_status */ - extensionPresent = FDKreadBits(bs, 1); /* ancillary_data_extension_status; */ - compressionPresent = FDKreadBits(bs, 1); /* audio_coding_mode_and_compression status */ - coarseGrainTcPresent = FDKreadBits(bs, 1); /* coarse_grain_timecode_status */ - fineGrainTcPresent = FDKreadBits(bs, 1); /* fine_grain_timecode_status */ - bitCnt += 24; + dmxLevelsPresent = FDKreadBits(bs, 1); /* downmixing_levels_MPEG4_status */ + /*extensionPresent =*/FDKreadBits(bs, + 1); /* ancillary_data_extension_status; */ + compressionPresent = + FDKreadBits(bs, 1); /* audio_coding_mode_and_compression status */ + /*coarseGrainTcPresent =*/FDKreadBits(bs, + 1); /* coarse_grain_timecode_status */ + /*fineGrainTcPresent =*/FDKreadBits(bs, 1); /* fine_grain_timecode_status */ if (dmxLevelsPresent) { - FDKreadBits(bs, 8); /* downmixing_levels_MPEG4 */ - bitCnt += 8; + FDKreadBits(bs, 8); /* downmixing_levels_MPEG4 */ } /* audio_coding_mode_and_compression_status */ - if (compressionPresent) - { + if (compressionPresent) { UCHAR compressionOn, compressionValue; /* audio_coding_mode */ - if ( FDKreadBits(bs, 7) != 0 ) { /* The reserved bits shall be set to "0". */ + if (FDKreadBits(bs, 7) != 0) { /* The reserved bits shall be set to "0". */ return 0; } - compressionOn = (UCHAR)FDKreadBits(bs, 1); /* compression_on */ - compressionValue = (UCHAR)FDKreadBits(bs, 8); /* Compression_value */ - bitCnt += 16; - - if ( compressionOn ) { - /* A compression value is available so store the data just like MPEG DRC data */ - pDrcBs->channelData.numBands = 1; /* One band ... */ - pDrcBs->channelData.drcValue[0] = compressionValue; /* ... with one value ... */ - pDrcBs->channelData.bandTop[0] = (1024 >> 2) - 1; /* ... comprising the whole spectrum. */ - pDrcBs->pceInstanceTag = -1; /* Not present */ - pDrcBs->progRefLevel = -1; /* Not present */ - pDrcBs->channelData.drcDataType = DVB_DRC_ANC_DATA; /* Set DRC payload type to DVB. */ - } else { - /* No compression value available */ - /* CAUTION: It is not clearly defined by standard how to react in this situation. */ - /* Turn down the compression value to aprox. 0dB */ - pDrcBs->channelData.numBands = 1; /* One band ... */ - pDrcBs->channelData.drcValue[0] = 0x80; /* ... with aprox. 0dB ... */ - pDrcBs->channelData.bandTop[0] = (1024 >> 2) - 1; /* ... comprising the whole spectrum. */ - pDrcBs->channelData.drcDataType = DVB_DRC_ANC_DATA; /* Set DRC payload type to DVB. */ - - /* If compression_on field is set to "0" the compression_value field shall be "0000 0000". */ - if (compressionValue != 0) { - return 0; - } + compressionOn = (UCHAR)FDKreadBits(bs, 1); /* compression_on */ + compressionValue = (UCHAR)FDKreadBits(bs, 8); /* Compression_value */ + + if (compressionOn) { + /* A compression value is available so store the data just like MPEG DRC + * data */ + pDrcBs->channelData.numBands = 1; /* One band ... */ + pDrcBs->channelData.drcValue[0] = + compressionValue; /* ... with one value ... */ + pDrcBs->channelData.bandTop[0] = + DRC_BLOCK_LEN_DIV_BAND_MULT - + 1; /* ... comprising the whole spectrum. */ + ; + pDrcBs->pceInstanceTag = -1; /* Not present */ + pDrcBs->progRefLevel = -1; /* Not present */ + pDrcBs->channelData.drcDataType = + DVB_DRC_ANC_DATA; /* Set DRC payload type to DVB. */ + foundDrcData = 1; } } - /* Read timecodes if available just to get the right amount of bits. */ - if (coarseGrainTcPresent) { - FDKreadBits(bs, 16); /* coarse_grain_timecode */ - bitCnt += 16; - } - if (fineGrainTcPresent) { - FDKreadBits(bs, 16); /* fine_grain_timecode */ - bitCnt += 16; - } - - /* Read extension just to get the right amount of bits. */ - if (extensionPresent) { - int extBits = 8; - - FDKreadBits(bs, 1); /* reserved, set to 0 */ - if (FDKreadBits(bs, 1)) extBits += 8; /* ext_downmixing_levels_status */ - if (FDKreadBits(bs, 1)) extBits += 16; /* ext_downmixing_global_gains_status */ - if (FDKreadBits(bs, 1)) extBits += 8; /* ext_downmixing_lfe_level_status */ - - FDKpushFor(bs, extBits - 4); /* skip the extension payload remainder. */ - bitCnt += extBits; - } - - return (bitCnt); + return (foundDrcData); } - -/* - * Prepare DRC processing +/* + * Extract DRC payload from bitstream and map it to channels. + * Valid return values are: + * -1 : An unexpected error occured. + * 0 : No error and no valid DRC data available. + * 1 : No error and valid DRC data has been mapped. */ -static int aacDecoder_drcExtractAndMap ( - HANDLE_AAC_DRC self, - HANDLE_FDK_BITSTREAM hBs, - CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo[], - UCHAR pceInstanceTag, - UCHAR channelMapping[], /* Channel mapping translating drcChannel index to canonical channel index */ - int validChannels ) -{ - CDrcPayload threadBs[MAX_DRC_THREADS]; +static int aacDecoder_drcExtractAndMap( + HANDLE_AAC_DRC self, HANDLE_FDK_BITSTREAM hBs, + CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo[], + UCHAR pceInstanceTag, + UCHAR channelMapping[], /* Channel mapping translating drcChannel index to + canonical channel index */ + int validChannels) { + CDrcPayload threadBs[MAX_DRC_THREADS]; CDrcPayload *validThreadBs[MAX_DRC_THREADS]; - CDrcParams *pParams; + CDrcParams *pParams; UINT backupBsPosition; - int i, thread, validThreads = 0; - int numExcludedChns[MAX_DRC_THREADS]; + int result = 0; + int i, thread, validThreads = 0; FDK_ASSERT(self != NULL); FDK_ASSERT(hBs != NULL); @@ -687,45 +696,40 @@ static int aacDecoder_drcExtractAndMap ( self->numThreads = 0; backupBsPosition = FDKgetValidBits(hBs); - for (i = 0; i < self->numPayloads && self->numThreads < MAX_DRC_THREADS; i++) { - int bitsParsed; - - /* Init payload data chunk. The memclear is very important because it initializes - the most values. Without it the module wouldn't work properly or crash. */ + for (i = 0; i < self->numPayloads && self->numThreads < MAX_DRC_THREADS; + i++) { + /* Init payload data chunk. The memclear is very important because it + initializes the most values. Without it the module wouldn't work properly + or crash. */ FDKmemclear(&threadBs[self->numThreads], sizeof(CDrcPayload)); - threadBs[self->numThreads].channelData.bandTop[0] = (1024 >> 2) - 1; + threadBs[self->numThreads].channelData.bandTop[0] = + DRC_BLOCK_LEN_DIV_BAND_MULT - 1; /* Extract payload */ - bitsParsed = aacDecoder_drcParse( hBs, - &threadBs[self->numThreads], - self->drcPayloadPosition[i] ); - if (bitsParsed > 0) { - self->numThreads++; - } + self->numThreads += aacDecoder_drcParse(hBs, &threadBs[self->numThreads], + self->drcPayloadPosition[i]); } self->numPayloads = 0; - if (self->dvbAncDataAvailable && self->numThreads < MAX_DRC_THREADS) - { /* Append a DVB heavy compression payload thread if available. */ - int bitsParsed; + if (self->dvbAncDataAvailable && + self->numThreads < MAX_DRC_THREADS) { /* Append a DVB heavy compression + payload thread if available. */ - /* Init payload data chunk. The memclear is very important because it initializes - the most values. Without it the module wouldn't work properly or crash. */ + /* Init payload data chunk. The memclear is very important because it + initializes the most values. Without it the module wouldn't work properly + or crash. */ FDKmemclear(&threadBs[self->numThreads], sizeof(CDrcPayload)); - threadBs[self->numThreads].channelData.bandTop[0] = (1024 >> 2) - 1; + threadBs[self->numThreads].channelData.bandTop[0] = + DRC_BLOCK_LEN_DIV_BAND_MULT - 1; /* Extract payload */ - bitsParsed = aacDecoder_drcReadCompression( hBs, - &threadBs[self->numThreads], - self->dvbAncDataPosition ); - if (bitsParsed > 0) { - self->numThreads++; - } + self->numThreads += aacDecoder_drcReadCompression( + hBs, &threadBs[self->numThreads], self->dvbAncDataPosition); } self->dvbAncDataAvailable = 0; /* Reset the bitbufffer */ - FDKpushBiDirectional(hBs, FDKgetValidBits(hBs) - backupBsPosition); + FDKpushBiDirectional(hBs, (INT)FDKgetValidBits(hBs) - (INT)backupBsPosition); /* calculate number of valid bits in excl_chn_mask */ @@ -744,9 +748,9 @@ static int aacDecoder_drcExtractAndMap ( break; } - if (pThreadBs->pceInstanceTag >= 0) { /* if PCE tag present */ + if (pThreadBs->pceInstanceTag >= 0) { /* if PCE tag present */ if (pThreadBs->pceInstanceTag != pceInstanceTag) { - continue; /* don't accept */ + continue; /* don't accept */ } } @@ -760,44 +764,17 @@ static int aacDecoder_drcExtractAndMap ( } } if (numExclChns < validChannels) { - validThreadBs[validThreads] = pThreadBs; - numExcludedChns[validThreads] = numExclChns; + validThreadBs[validThreads] = pThreadBs; validThreads++; } } - if (validThreads > 1) { - int ch; - - /* check consistency of excl_chn_mask amongst valid DRC threads */ - for (ch = 0; ch < validChannels; ch++) { - int present = 0; - - for (thread = 0; thread < validThreads; thread++) { - CDrcPayload *pThreadBs = validThreadBs[thread]; - - - /* thread applies to this channel */ - if ( (pThreadBs->channelData.drcDataType == MPEG_DRC_EXT_DATA) - && ( (numExcludedChns[thread] == 0) - || (!(pThreadBs->excludedChnsMask & (1<<ch))) ) ) { - present++; - } - } - - - if (present > 1) { - return -1; - } - } - } - /* map DRC bitstream information onto DRC channel information */ - for (thread = 0; thread < validThreads; thread++) - { + for (thread = 0; thread < validThreads; thread++) { CDrcPayload *pThreadBs = validThreadBs[thread]; INT exclMask = pThreadBs->excludedChnsMask; - AACDEC_DRC_PAYLOAD_TYPE drcPayloadType = (AACDEC_DRC_PAYLOAD_TYPE)pThreadBs->channelData.drcDataType; + AACDEC_DRC_PAYLOAD_TYPE drcPayloadType = + (AACDEC_DRC_PAYLOAD_TYPE)pThreadBs->channelData.drcDataType; int ch; /* last progRefLevel transmitted is the one that is used @@ -806,7 +783,7 @@ static int aacDecoder_drcExtractAndMap ( if (pThreadBs->progRefLevel >= 0) { self->progRefLevel = pThreadBs->progRefLevel; self->progRefLevelPresent = 1; - self->prlExpiryCount = 0; /* Got a new value -> Reset counter */ + self->prlExpiryCount = 0; /* Got a new value -> Reset counter */ } if (drcPayloadType == DVB_DRC_ANC_DATA) { @@ -816,43 +793,51 @@ static int aacDecoder_drcExtractAndMap ( /* SCE, CPE and LFE */ for (ch = 0; ch < validChannels; ch++) { + AACDEC_DRC_PAYLOAD_TYPE prvPayloadType = UNKNOWN_PAYLOAD; int mapedChannel = channelMapping[ch]; - if ( ((exclMask & (1<<mapedChannel)) == 0) - && ( (drcPayloadType == MPEG_DRC_EXT_DATA) - || ((drcPayloadType == DVB_DRC_ANC_DATA) && self->params.applyHeavyCompression) - ) ) { - /* copy thread to channel */ + if ((mapedChannel >= validChannels) || + ((exclMask & (1 << mapedChannel)) != 0)) + continue; + + if ((pParams->expiryFrame <= 0) || + (pAacDecoderStaticChannelInfo[ch]->drcData.expiryCount < + pParams->expiryFrame)) { + prvPayloadType = + (AACDEC_DRC_PAYLOAD_TYPE)pAacDecoderStaticChannelInfo[ch] + ->drcData.drcDataType; + } + if (((drcPayloadType == MPEG_DRC_EXT_DATA) && + (prvPayloadType != DVB_DRC_ANC_DATA)) || + ((drcPayloadType == DVB_DRC_ANC_DATA) && + (pParams->applyHeavyCompression == + ON))) { /* copy thread to channel */ pAacDecoderStaticChannelInfo[ch]->drcData = pThreadBs->channelData; + result = 1; } } /* CCEs not supported by now */ } /* Increment and check expiry counter for the program reference level: */ - if ( (pParams->expiryFrame > 0) - && (self->prlExpiryCount++ > pParams->expiryFrame) ) - { /* The program reference level is too old, so set it back to the target level. */ + if ((pParams->expiryFrame > 0) && + (self->prlExpiryCount++ > + pParams->expiryFrame)) { /* The program reference level is too old, so + set it back to the target level. */ self->progRefLevelPresent = 0; self->progRefLevel = pParams->targetRefLevel; self->prlExpiryCount = 0; } - return 0; + return result; } - -void aacDecoder_drcApply ( - HANDLE_AAC_DRC self, - void *pSbrDec, - CAacDecoderChannelInfo *pAacDecoderChannelInfo, - CDrcChannelData *pDrcChData, - FIXP_DBL *extGain, - int ch, /* needed only for SBR */ - int aacFrameSize, - int bSbrPresent ) -{ - int band, top, bin, numBands; +void aacDecoder_drcApply(HANDLE_AAC_DRC self, void *pSbrDec, + CAacDecoderChannelInfo *pAacDecoderChannelInfo, + CDrcChannelData *pDrcChData, FIXP_DBL *extGain, + int ch, /* needed only for SBR */ + int aacFrameSize, int bSbrPresent) { + int band, bin, numBands; int bottom = 0; int modifyBins = 0; @@ -860,33 +845,35 @@ void aacDecoder_drcApply ( INT max_exponent; FIXP_DBL norm_mantissa = FL2FXCONST_DBL(0.5f); - INT norm_exponent = 1; + INT norm_exponent = 1; FIXP_DBL fact_mantissa[MAX_DRC_BANDS]; - INT fact_exponent[MAX_DRC_BANDS]; + INT fact_exponent[MAX_DRC_BANDS]; - CDrcParams *pParams = &self->params; + CDrcParams *pParams = &self->params; - FIXP_DBL *pSpectralCoefficient = SPEC_LONG(pAacDecoderChannelInfo->pSpectralCoefficient); - CIcsInfo *pIcsInfo = &pAacDecoderChannelInfo->icsInfo; - SHORT *pSpecScale = pAacDecoderChannelInfo->specScale; + FIXP_DBL *pSpectralCoefficient = + SPEC_LONG(pAacDecoderChannelInfo->pSpectralCoefficient); + CIcsInfo *pIcsInfo = &pAacDecoderChannelInfo->icsInfo; + SHORT *pSpecScale = pAacDecoderChannelInfo->specScale; int winSeq = pIcsInfo->WindowSequence; /* Increment and check expiry counter */ - if ( (pParams->expiryFrame > 0) - && (++pDrcChData->expiryCount > pParams->expiryFrame) ) - { /* The DRC data is too old, so delete it. */ - aacDecoder_drcInitChannelData( pDrcChData ); + if ((pParams->expiryFrame > 0) && + (++pDrcChData->expiryCount > + pParams->expiryFrame)) { /* The DRC data is too old, so delete it. */ + aacDecoder_drcInitChannelData(pDrcChData); } - if (!self->enable) { - sbrDecoder_drcDisable( (HANDLE_SBRDECODER)pSbrDec, ch ); + if (self->enable != ON) { + sbrDecoder_drcDisable((HANDLE_SBRDECODER)pSbrDec, ch); if (extGain != NULL) { INT gainScale = (INT)*extGain; - /* The gain scaling must be passed to the function in the buffer pointed on by extGain. */ + /* The gain scaling must be passed to the function in the buffer pointed + * on by extGain. */ if (gainScale >= 0 && gainScale <= DFRACT_BITS) { - *extGain = scaleValue(norm_mantissa, norm_exponent-gainScale); + *extGain = scaleValue(norm_mantissa, norm_exponent - gainScale); } else { FDK_ASSERT(0); } @@ -895,9 +882,6 @@ void aacDecoder_drcApply ( } numBands = pDrcChData->numBands; - top = FDKmax(0, numBands-1); - - pDrcChData->bandTop[0] = fixMin(pDrcChData->bandTop[0], (aacFrameSize >> 2) - 1); /* If program reference normalization is done in the digital domain, modify factor to perform normalization. prog_ref_level can @@ -906,45 +890,42 @@ void aacDecoder_drcApply ( reduced DAC SNR (if signal is attenuated) or clipping (if signal is boosted) */ - if (pParams->targetRefLevel >= 0) - { + if (pParams->targetRefLevel >= 0) { /* 0.5^((targetRefLevel - progRefLevel)/24) */ - norm_mantissa = fLdPow( - FL2FXCONST_DBL(-1.0), /* log2(0.5) */ - 0, - (FIXP_DBL)((INT)(FL2FXCONST_DBL(1.0f/24.0)>>3) * (INT)(pParams->targetRefLevel-self->progRefLevel)), - 3, - &norm_exponent ); + norm_mantissa = + fLdPow(FL2FXCONST_DBL(-1.0), /* log2(0.5) */ + 0, + (FIXP_DBL)((INT)(FL2FXCONST_DBL(1.0f / 24.0) >> 3) * + (INT)(pParams->targetRefLevel - self->progRefLevel)), + 3, &norm_exponent); } /* Always export the normalization gain (if possible). */ if (extGain != NULL) { INT gainScale = (INT)*extGain; - /* The gain scaling must be passed to the function in the buffer pointed on by extGain. */ + /* The gain scaling must be passed to the function in the buffer pointed on + * by extGain. */ if (gainScale >= 0 && gainScale <= DFRACT_BITS) { - *extGain = scaleValue(norm_mantissa, norm_exponent-gainScale); + *extGain = scaleValue(norm_mantissa, norm_exponent - gainScale); } else { FDK_ASSERT(0); } } - if (self->params.applyDigitalNorm == 0) { + if (self->params.applyDigitalNorm == OFF) { /* Reset normalization gain since this module must not apply it */ norm_mantissa = FL2FXCONST_DBL(0.5f); norm_exponent = 1; } - /* calc scale factors */ - for (band = 0; band < numBands; band++) - { + for (band = 0; band < numBands; band++) { UCHAR drcVal = pDrcChData->drcValue[band]; - top = fixMin((int)( (pDrcChData->bandTop[band]+1)<<2 ), aacFrameSize); fact_mantissa[band] = FL2FXCONST_DBL(0.5f); fact_exponent[band] = 1; - if ( pParams->applyHeavyCompression - && ((AACDEC_DRC_PAYLOAD_TYPE)pDrcChData->drcDataType == DVB_DRC_ANC_DATA) ) - { + if ((pParams->applyHeavyCompression == ON) && + ((AACDEC_DRC_PAYLOAD_TYPE)pDrcChData->drcDataType == + DVB_DRC_ANC_DATA)) { INT compressionFactorVal_e; int valX, valY; @@ -954,48 +935,44 @@ void aacDecoder_drcApply ( /* calculate the unscaled heavy compression factor. compressionFactor = 48.164 - 6.0206*valX - 0.4014*valY dB range: -48.166 dB to 48.164 dB */ - if ( drcVal != 0x7F ) { - fact_mantissa[band] = - fPowInt( FL2FXCONST_DBL(0.95483867181), /* -0.4014dB = 0.95483867181 */ - 0, - valY, - &compressionFactorVal_e ); + if (drcVal != 0x7F) { + fact_mantissa[band] = fPowInt( + FL2FXCONST_DBL(0.95483867181), /* -0.4014dB = 0.95483867181 */ + 0, valY, &compressionFactorVal_e); /* -0.0008dB (48.164 - 6.0206*8 = -0.0008) */ - fact_mantissa[band] = fMult(FL2FXCONST_DBL(0.99990790084), fact_mantissa[band]); + fact_mantissa[band] = + fMult(FL2FXCONST_DBL(0.99990790084), fact_mantissa[band]); - fact_exponent[band] = DVB_COMPRESSION_SCALE - valX + compressionFactorVal_e; + fact_exponent[band] = + DVB_COMPRESSION_SCALE - valX + compressionFactorVal_e; + } + } else if ((AACDEC_DRC_PAYLOAD_TYPE)pDrcChData->drcDataType == + MPEG_DRC_EXT_DATA) { + /* apply the scaled dynamic range control words to factor. + * if scaling drc_cut (or drc_boost), or control word drc_mantissa is 0 + * then there is no dynamic range compression + * + * if pDrcChData->drcSgn[band] is + * 1 then gain is < 1 : factor = 2^(-self->cut * + * pDrcChData->drcMag[band] / 24) 0 then gain is > 1 : factor = 2^( + * self->boost * pDrcChData->drcMag[band] / 24) + */ + + if ((drcVal & 0x7F) > 0) { + FIXP_DBL tParamVal = (drcVal & 0x80) ? -pParams->cut : pParams->boost; + + fact_mantissa[band] = f2Pow( + (FIXP_DBL)((INT)fMult(FL2FXCONST_DBL(1.0f / 192.0f), tParamVal) * + (drcVal & 0x7F)), + 3 + DRC_PARAM_SCALE, &fact_exponent[band]); } - } else - if ((AACDEC_DRC_PAYLOAD_TYPE)pDrcChData->drcDataType == MPEG_DRC_EXT_DATA) - { - /* apply the scaled dynamic range control words to factor. - * if scaling drc_cut (or drc_boost), or control word drc_mantissa is 0 - * then there is no dynamic range compression - * - * if pDrcChData->drcSgn[band] is - * 1 then gain is < 1 : factor = 2^(-self->cut * pDrcChData->drcMag[band] / 24) - * 0 then gain is > 1 : factor = 2^( self->boost * pDrcChData->drcMag[band] / 24) - */ - - if ((drcVal&0x7F) > 0) { - FIXP_DBL tParamVal = (drcVal & 0x80) ? -pParams->cut : pParams->boost; - - fact_mantissa[band] = - f2Pow( (FIXP_DBL)((INT)fMult(FL2FXCONST_DBL(1.0f/192.0f), tParamVal) * (drcVal&0x7F)), - 3+DRC_PARAM_SCALE, - &fact_exponent[band] ); - } } - fact_mantissa[band] = fMult(fact_mantissa[band], norm_mantissa); + fact_mantissa[band] = fMult(fact_mantissa[band], norm_mantissa); fact_exponent[band] += norm_exponent; - - bottom = top; - - } /* end loop over bands */ - + } /* end loop over bands */ /* normalizations */ { @@ -1012,7 +989,8 @@ void aacDecoder_drcApply ( res = CntLeadingZeros(max_mantissa) - 1; /* above topmost DRC band gain factor is 1 */ - if (((pDrcChData->bandTop[numBands-1]+1)<<2) < aacFrameSize) res = 0; + if (((pDrcChData->bandTop[fMax(0, numBands - 1)] + 1) << 2) < aacFrameSize) + res = 0; if (res > 0) { res = fixMin(res, max_exponent); @@ -1020,7 +998,7 @@ void aacDecoder_drcApply ( for (band = 0; band < numBands; band++) { fact_mantissa[band] <<= res; - fact_exponent[band] -= res; + fact_exponent[band] -= res; } } @@ -1039,25 +1017,25 @@ void aacDecoder_drcApply ( } /* apply factor to spectral lines - * short blocks must take care that bands fall on + * short blocks must take care that bands fall on * block boundaries! */ - if (!bSbrPresent) - { + if (!bSbrPresent) { bottom = 0; if (!modifyBins) { - /* We don't have to modify the spectral bins because the fractional part of all factors is 0.5. - In order to keep accurancy we don't apply the factor but decrease the exponent instead. */ + /* We don't have to modify the spectral bins because the fractional part + of all factors is 0.5. In order to keep accurancy we don't apply the + factor but decrease the exponent instead. */ max_exponent -= 1; - } else - { - for (band = 0; band < numBands; band++) - { - top = fixMin((int)( (pDrcChData->bandTop[band]+1)<<2 ), aacFrameSize); /* ... * DRC_BAND_MULT; */ + } else { + for (band = 0; band < numBands; band++) { + int top = fixMin((int)((pDrcChData->bandTop[band] + 1) << 2), + aacFrameSize); /* ... * DRC_BAND_MULT; */ for (bin = bottom; bin < top; bin++) { - pSpectralCoefficient[bin] = fMult(pSpectralCoefficient[bin], fact_mantissa[band]); + pSpectralCoefficient[bin] = + fMult(pSpectralCoefficient[bin], fact_mantissa[band]); } bottom = top; @@ -1066,7 +1044,7 @@ void aacDecoder_drcApply ( /* above topmost DRC band gain factor is 1 */ if (max_exponent > 0) { - for (bin = bottom; bin < aacFrameSize; bin+=1) { + for (bin = bottom; bin < aacFrameSize; bin += 1) { pSpectralCoefficient[bin] >>= max_exponent; } } @@ -1074,105 +1052,294 @@ void aacDecoder_drcApply ( /* adjust scaling */ pSpecScale[0] += max_exponent; - if (winSeq == EightShortSequence) { + if (winSeq == BLOCK_SHORT) { int win; for (win = 1; win < 8; win++) { pSpecScale[win] += max_exponent; } } - } - else { + } else { HANDLE_SBRDECODER hSbrDecoder = (HANDLE_SBRDECODER)pSbrDec; - UINT numBands = pDrcChData->numBands; + numBands = pDrcChData->numBands; /* feed factors into SBR decoder for application in QMF domain. */ - sbrDecoder_drcFeedChannel ( - hSbrDecoder, - ch, - numBands, - fact_mantissa, - max_exponent, - pDrcChData->drcInterpolationScheme, - winSeq, - pDrcChData->bandTop - ); + sbrDecoder_drcFeedChannel(hSbrDecoder, ch, numBands, fact_mantissa, + max_exponent, pDrcChData->drcInterpolationScheme, + winSeq, pDrcChData->bandTop); } return; } +/* + * DRC parameter and presentation mode handling + */ +static void aacDecoder_drcParameterHandling(HANDLE_AAC_DRC self, + INT aacNumChannels, + SCHAR prevDrcProgRefLevel, + SCHAR prevDrcPresMode) { + int isDownmix, isMonoDownmix, isStereoDownmix; + int dDmx, dHr; + AACDEC_DRC_PARAMETER_HANDLING drcParameterHandling; + CDrcParams *p; + + FDK_ASSERT(self != NULL); + + p = &self->params; + + if (self->progRefLevel != prevDrcProgRefLevel) self->update = 1; + + if (self->presMode != prevDrcPresMode) self->update = 1; -/* + if (self->prevAacNumChannels != aacNumChannels) self->update = 1; + + /* return if no relevant parameter has changed */ + if (!self->update) { + return; + } + + /* derive downmix property. aacNumChannels: number of channels in aac stream, + * numOutChannels: number of output channels */ + isDownmix = (aacNumChannels > self->numOutChannels); + isDownmix = (isDownmix && (self->numOutChannels > 0)); + isMonoDownmix = (isDownmix && (self->numOutChannels == 1)); + isStereoDownmix = (isDownmix && (self->numOutChannels == 2)); + + if ((self->presMode == 1) || (self->presMode == 2)) { + drcParameterHandling = (AACDEC_DRC_PARAMETER_HANDLING)self->presMode; + } else { /* no presentation mode -> use parameter handling specified by + AAC_DRC_DEFAULT_PRESENTATION_MODE */ + drcParameterHandling = p->defaultPresentationMode; + } + + /* by default, do as desired */ + p->cut = p->usrCut; + p->boost = p->usrBoost; + p->applyHeavyCompression = p->usrApplyHeavyCompression; + + switch (drcParameterHandling) { + case DISABLED_PARAMETER_HANDLING: + default: + /* use drc parameters as requested */ + break; + + case ENABLED_PARAMETER_HANDLING: + /* dDmx: estimated headroom reduction due to downmix, format: -1/4*dB + dDmx = floor(-4*20*log10(aacNumChannels/numOutChannels)) */ + if (isDownmix) { + FIXP_DBL dmxTmp; + int e_log, e_mult; + dmxTmp = fDivNorm(self->numOutChannels, + aacNumChannels); /* inverse division -> + negative sign after + logarithm */ + dmxTmp = fLog2(dmxTmp, 0, &e_log); + dmxTmp = fMultNorm( + dmxTmp, FL2FXCONST_DBL(4.0f * 20.0f * 0.30103f / (float)(1 << 5)), + &e_mult); /* e = e_log + e_mult + 5 */ + dDmx = (int)scaleValue(dmxTmp, e_log + e_mult + 5 - (DFRACT_BITS - 1)); + } else { + dDmx = 0; + } + + /* dHr: Full estimated (decoder) headroom reduction due to loudness + * normalisation (DTL - PRL) and downmix. Format: -1/4*dB */ + if (p->targetRefLevel >= 0) { /* if target level is provided */ + dHr = p->targetRefLevel + dDmx - self->progRefLevel; + } else { + dHr = dDmx; + } + + if (dHr < 0) { /* if headroom is reduced */ + /* Use compression, but as little as possible. */ + /* eHr: Headroom provided by encoder, format: -1/4 dB */ + int eHr = fixMin(p->encoderTargetLevel - self->progRefLevel, 0); + if (eHr < + dHr) { /* if encoder provides more headroom than decoder needs */ + /* derive scaling of light DRC */ + FIXP_DBL calcFactor_norm; + INT calcFactor; /* fraction of DRC gains that is minimally needed for + clipping prevention */ + calcFactor_norm = + fDivNorm(-dHr, -eHr); /* 0.0 < calcFactor_norm < 1.0 */ + calcFactor_norm = calcFactor_norm >> DRC_PARAM_SCALE; + /* quantize to 128 steps */ + calcFactor = convert_drcParam( + calcFactor_norm); /* convert to integer value between 0 and 127 */ + calcFactor_norm = (FIXP_DBL)( + (INT)(DRC_PARAM_QUANT_STEP >> DRC_PARAM_SCALE) * calcFactor); + p->cut = (calcFactor_norm > p->cut) + ? calcFactor_norm + : p->cut; /* use calcFactor_norm as lower limit */ + } else { + /* encoder provides equal or less headroom than decoder needs */ + /* the time domain limiter must always be active in this case. It is + * assumed that the framework activates it by default */ + p->cut = DRC_SCALING_MAX; + if ((dHr - eHr) <= + -4 * DRC_HEAVY_THRESHOLD_DB) { /* use heavy compression if + headroom deficit is equal or + higher than + DRC_HEAVY_THRESHOLD_DB */ + p->applyHeavyCompression = ON; + } + } + } else { /* dHr >= 0 */ + /* no restrictions required, as headroom is not reduced. */ + /* p->cut = p->usrCut; */ + } + break; + + /* presentation mode 1 and 2 according to ETSI TS 101 154: + Digital Video Broadcasting (DVB); Specification for the use of Video + and Audio Coding in Broadcasting Applications based on the MPEG-2 + Transport Stream, section C.5.4., "Decoding", and Table C.33. Also + according to amendment 4 to ISO/IEC 14496-3, section 4.5.2.14.2.4, and + Table AMD4.11. ISO DRC -> applyHeavyCompression = OFF (Use + light compression, MPEG-style) Compression_value -> + applyHeavyCompression = ON (Use heavy compression, DVB-style) scaling + restricted -> p->cut = DRC_SCALING_MAX */ + + case DRC_PRESENTATION_MODE_1: /* presentation mode 1, Light:-31/Heavy:-23 */ + if ((p->targetRefLevel >= 0) && + (p->targetRefLevel < + 124)) { /* if target level is provided and > -31 dB */ + /* playback up to -23 dB */ + p->applyHeavyCompression = ON; + } else { /* target level <= -31 dB or not provided */ + /* playback -31 dB */ + if (isMonoDownmix || isStereoDownmix) { /* stereo or mono downmixing */ + p->cut = DRC_SCALING_MAX; + } + } + break; + + case DRC_PRESENTATION_MODE_2: /* presentation mode 2, Light:-23/Heavy:-23 */ + if ((p->targetRefLevel >= 0) && + (p->targetRefLevel < + 124)) { /* if target level is provided and > -31 dB */ + /* playback up to -23 dB */ + if (isMonoDownmix) { /* if mono downmix */ + p->applyHeavyCompression = ON; + } else { + p->applyHeavyCompression = OFF; + p->cut = DRC_SCALING_MAX; + } + } else { /* target level <= -31 dB or not provided */ + /* playback -31 dB */ + p->applyHeavyCompression = OFF; + if (isMonoDownmix || isStereoDownmix) { /* stereo or mono downmixing */ + p->cut = DRC_SCALING_MAX; + } + } + break; + } /* switch (drcParameterHandling) */ + + /* With heavy compression, there is no scaling. + Scaling factors are set for notification only. */ + if (p->applyHeavyCompression == ON) { + p->boost = DRC_SCALING_MAX; + p->cut = DRC_SCALING_MAX; + } + + /* switch on/off processing */ + self->enable = ((p->boost > (FIXP_DBL)0) || (p->cut > (FIXP_DBL)0) || + (p->applyHeavyCompression == ON) || (p->targetRefLevel >= 0)); + self->enable = (self->enable && !self->uniDrcPrecedence); + + self->prevAacNumChannels = aacNumChannels; + self->update = 0; +} + +/* * Prepare DRC processing + * Valid return values are: + * -1 : An unexpected error occured. + * 0 : No error and no valid DRC data available. + * 1 : No error and valid DRC data has been mapped. */ -int aacDecoder_drcProlog ( - HANDLE_AAC_DRC self, - HANDLE_FDK_BITSTREAM hBs, - CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo[], - UCHAR pceInstanceTag, - UCHAR channelMapping[], /* Channel mapping translating drcChannel index to canonical channel index */ - int validChannels ) -{ - int err = 0; +int aacDecoder_drcProlog( + HANDLE_AAC_DRC self, HANDLE_FDK_BITSTREAM hBs, + CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo[], + UCHAR pceInstanceTag, + UCHAR channelMapping[], /* Channel mapping translating drcChannel index to + canonical channel index */ + int validChannels) { + int result = 0; if (self == NULL) { return -1; } - if (!self->params.bsDelayEnable) - { - err = aacDecoder_drcExtractAndMap ( - self, - hBs, - pAacDecoderStaticChannelInfo, - pceInstanceTag, - channelMapping, - validChannels ); + if (!self->params.bsDelayEnable) { + /* keep previous progRefLevel and presMode for update flag in + * drcParameterHandling */ + INT prevPRL, prevPM = 0; + prevPRL = self->progRefLevel; + prevPM = self->presMode; + + result = aacDecoder_drcExtractAndMap( + self, hBs, pAacDecoderStaticChannelInfo, pceInstanceTag, channelMapping, + validChannels); + + if (result < 0) { + return result; + } + + /* Drc parameter handling */ + aacDecoder_drcParameterHandling(self, validChannels, prevPRL, prevPM); } - return err; + return result; } - -/* +/* * Finalize DRC processing + * Valid return values are: + * -1 : An unexpected error occured. + * 0 : No error and no valid DRC data available. + * 1 : No error and valid DRC data has been mapped. */ -int aacDecoder_drcEpilog ( - HANDLE_AAC_DRC self, - HANDLE_FDK_BITSTREAM hBs, - CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo[], - UCHAR pceInstanceTag, - UCHAR channelMapping[], /* Channel mapping translating drcChannel index to canonical channel index */ - int validChannels ) -{ - int err = 0; +int aacDecoder_drcEpilog( + HANDLE_AAC_DRC self, HANDLE_FDK_BITSTREAM hBs, + CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo[], + UCHAR pceInstanceTag, + UCHAR channelMapping[], /* Channel mapping translating drcChannel index to + canonical channel index */ + int validChannels) { + int result = 0; if (self == NULL) { return -1; } - if (self->params.bsDelayEnable) - { - err = aacDecoder_drcExtractAndMap ( - self, - hBs, - pAacDecoderStaticChannelInfo, - pceInstanceTag, - channelMapping, - validChannels ); + if (self->params.bsDelayEnable) { + /* keep previous progRefLevel and presMode for update flag in + * drcParameterHandling */ + INT prevPRL, prevPM = 0; + prevPRL = self->progRefLevel; + prevPM = self->presMode; + + result = aacDecoder_drcExtractAndMap( + self, hBs, pAacDecoderStaticChannelInfo, pceInstanceTag, channelMapping, + validChannels); + + if (result < 0) { + return result; + } + + /* Drc parameter handling */ + aacDecoder_drcParameterHandling(self, validChannels, prevPRL, prevPM); } - return err; + return result; } /* * Export relevant metadata info from bitstream payload. */ -void aacDecoder_drcGetInfo ( - HANDLE_AAC_DRC self, - SCHAR *pPresMode, - SCHAR *pProgRefLevel ) -{ +void aacDecoder_drcGetInfo(HANDLE_AAC_DRC self, SCHAR *pPresMode, + SCHAR *pProgRefLevel) { if (self != NULL) { if (pPresMode != NULL) { *pPresMode = self->presMode; |