aboutsummaryrefslogtreecommitdiffstats
path: root/libAACdec/src/aacdec_drc.cpp
diff options
context:
space:
mode:
authorFraunhofer IIS FDK <audio-fdk@iis.fraunhofer.de>2018-02-26 20:17:00 +0100
committerJean-Michel Trivi <jmtrivi@google.com>2018-04-19 11:21:15 -0700
commit6cfabd35363c3ef5e3b209b867169a500b3ccc3c (patch)
tree01c0a19f2735e8b5d2407555fe992d4230d089eb /libAACdec/src/aacdec_drc.cpp
parent6288a1e34c4dede4c2806beb1736ece6580558c7 (diff)
downloadfdk-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.cpp1389
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;