diff options
Diffstat (limited to 'libAACenc/src/qc_main.cpp')
-rw-r--r-- | libAACenc/src/qc_main.cpp | 1644 |
1 files changed, 0 insertions, 1644 deletions
diff --git a/libAACenc/src/qc_main.cpp b/libAACenc/src/qc_main.cpp deleted file mode 100644 index 9866a3a..0000000 --- a/libAACenc/src/qc_main.cpp +++ /dev/null @@ -1,1644 +0,0 @@ - -/* ----------------------------------------------------------------------------------------------------------- -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. - - 1. INTRODUCTION -The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements -the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. -This FDK AAC Codec software is intended to be used on a wide variety of Android devices. - -AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual -audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by -independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part -of the MPEG specifications. - -Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) -may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners -individually for the purpose of encoding or decoding bit streams in products that are compliant with -the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license -these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec -software may already be covered under those patent licenses when it is used for those licensed purposes only. - -Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, -are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional -applications information and documentation. - -2. COPYRIGHT LICENSE - -Redistribution and use in source and binary forms, with or without modification, are permitted without -payment of copyright license fees provided that you satisfy the following conditions: - -You must retain the complete text of this software license in redistributions of the FDK AAC Codec or -your modifications thereto in source code form. - -You must retain the complete text of this software license in the documentation and/or other materials -provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. -You must make available free of charge copies of the complete source code of the FDK AAC Codec and your -modifications thereto to recipients of copies in binary form. - -The name of Fraunhofer may not be used to endorse or promote products derived from this library without -prior written permission. - -You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec -software or your modifications thereto. - -Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software -and the date of any change. For modified versions of the FDK AAC Codec, the term -"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term -"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." - -3. NO PATENT LICENSE - -NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, -ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with -respect to this software. - -You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized -by appropriate patent licenses. - -4. DISCLAIMER - -This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors -"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties -of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, -including but not limited to procurement of substitute goods or services; loss of use, data, or profits, -or business interruption, however caused and on any theory of liability, whether in contract, strict -liability, or tort (including negligence), arising in any way out of the use of this software, even if -advised of the possibility of such damage. - -5. CONTACT INFORMATION - -Fraunhofer Institute for Integrated Circuits IIS -Attention: Audio and Multimedia Departments - FDK AAC LL -Am Wolfsmantel 33 -91058 Erlangen, Germany - -www.iis.fraunhofer.de/amm -amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ - -/******************************** MPEG Audio Encoder ************************** - - Initial author: M. Werner - contents/description: Quantizing & coding - -******************************************************************************/ -#include <stdio.h> -#include "qc_main.h" -#include "quantize.h" -#include "interface.h" -#include "adj_thr.h" -#include "sf_estim.h" -#include "bit_cnt.h" -#include "dyn_bits.h" -#include "channel_map.h" -#include "aacEnc_ram.h" - -#include "genericStds.h" - - -typedef struct { - QCDATA_BR_MODE bitrateMode; - LONG vbrQualFactor; -} TAB_VBR_QUAL_FACTOR; - -static const TAB_VBR_QUAL_FACTOR tableVbrQualFactor[] = { - {QCDATA_BR_MODE_CBR, FL2FXCONST_DBL(0.00f)}, - {QCDATA_BR_MODE_VBR_1, FL2FXCONST_DBL(0.160f)}, /* 32 kbps mono AAC-LC + SBR + PS */ - {QCDATA_BR_MODE_VBR_2, FL2FXCONST_DBL(0.148f)}, /* 64 kbps stereo AAC-LC + SBR */ - {QCDATA_BR_MODE_VBR_3, FL2FXCONST_DBL(0.135f)}, /* 80 - 96 kbps stereo AAC-LC */ - {QCDATA_BR_MODE_VBR_4, FL2FXCONST_DBL(0.111f)}, /* 128 kbps stereo AAC-LC */ - {QCDATA_BR_MODE_VBR_5, FL2FXCONST_DBL(0.070f)}, /* 192 kbps stereo AAC-LC */ - {QCDATA_BR_MODE_SFR, FL2FXCONST_DBL(0.00f)}, - {QCDATA_BR_MODE_FF, FL2FXCONST_DBL(0.00f)} -}; - -static INT isConstantBitrateMode( - const QCDATA_BR_MODE bitrateMode - ) -{ - return ( ((bitrateMode==QCDATA_BR_MODE_CBR) || (bitrateMode==QCDATA_BR_MODE_SFR) || (bitrateMode==QCDATA_BR_MODE_FF)) ? 1 : 0 ); -} - - - -typedef enum{ - FRAME_LEN_BYTES_MODULO = 1, - FRAME_LEN_BYTES_INT = 2 -}FRAME_LEN_RESULT_MODE; - -/* forward declarations */ - -static INT FDKaacEnc_calcMaxValueInSfb(INT sfbCnt, - INT maxSfbPerGroup, - INT sfbPerGroup, - INT *RESTRICT sfbOffset, - SHORT *RESTRICT quantSpectrum, - UINT *RESTRICT maxValue); - -static void FDKaacEnc_crashRecovery(INT nChannels, - PSY_OUT_ELEMENT* psyOutElement, - QC_OUT* qcOut, - QC_OUT_ELEMENT *qcElement, - INT bitsToSave, - AUDIO_OBJECT_TYPE aot, - UINT syntaxFlags, - SCHAR epConfig); - -static -AAC_ENCODER_ERROR FDKaacEnc_reduceBitConsumption(int* iterations, - const int maxIterations, - int gainAdjustment, - int* chConstraintsFulfilled, - int* calculateQuant, - int nChannels, - PSY_OUT_ELEMENT* psyOutElement, - QC_OUT* qcOut, - QC_OUT_ELEMENT* qcOutElement, - ELEMENT_BITS* elBits, - AUDIO_OBJECT_TYPE aot, - UINT syntaxFlags, - SCHAR epConfig); - - -void FDKaacEnc_QCClose (QC_STATE **phQCstate, QC_OUT **phQC); - -/***************************************************************************** - - functionname: FDKaacEnc_calcFrameLen - description: - returns: - input: - output: - -*****************************************************************************/ -static INT FDKaacEnc_calcFrameLen(INT bitRate, - INT sampleRate, - INT granuleLength, - FRAME_LEN_RESULT_MODE mode) -{ - - INT result; - - result = ((granuleLength)>>3)*(bitRate); - - switch(mode) { - case FRAME_LEN_BYTES_MODULO: - result %= sampleRate; - break; - case FRAME_LEN_BYTES_INT: - result /= sampleRate; - break; - } - return(result); -} - -/***************************************************************************** - - functionname:FDKaacEnc_framePadding - description: Calculates if padding is needed for actual frame - returns: - input: - output: - -*****************************************************************************/ -static INT FDKaacEnc_framePadding(INT bitRate, - INT sampleRate, - INT granuleLength, - INT *paddingRest) -{ - INT paddingOn; - INT difference; - - paddingOn = 0; - - difference = FDKaacEnc_calcFrameLen( bitRate, - sampleRate, - granuleLength, - FRAME_LEN_BYTES_MODULO ); - *paddingRest-=difference; - - if (*paddingRest <= 0 ) { - paddingOn = 1; - *paddingRest += sampleRate; - } - - return( paddingOn ); -} - - -/********************************************************************************* - - functionname: FDKaacEnc_QCOutNew - description: - return: - -**********************************************************************************/ -AAC_ENCODER_ERROR FDKaacEnc_QCOutNew(QC_OUT **phQC, - const INT nElements, - const INT nChannels, - const INT nSubFrames - ,UCHAR *dynamic_RAM - ) -{ - AAC_ENCODER_ERROR ErrorStatus; - int n, i; - int elInc = 0, chInc = 0; - - for (n=0; n<nSubFrames; n++) { - phQC[n] = GetRam_aacEnc_QCout(n); - if (phQC[n] == NULL) { - ErrorStatus = AAC_ENC_NO_MEMORY; - goto QCOutNew_bail; - } - - for (i=0; i<nChannels; i++) { - phQC[n]->pQcOutChannels[i] = GetRam_aacEnc_QCchannel(chInc, dynamic_RAM); - if ( phQC[n]->pQcOutChannels[i] == NULL - ) - { - ErrorStatus = AAC_ENC_NO_MEMORY; - goto QCOutNew_bail; - } - chInc++; - } /* nChannels */ - - for (i=0; i<nElements; i++) { - phQC[n]->qcElement[i] = GetRam_aacEnc_QCelement(elInc); - if (phQC[n]->qcElement[i] == NULL) - { - ErrorStatus = AAC_ENC_NO_MEMORY; - goto QCOutNew_bail; - } - elInc++; - } /* nElements */ - - } /* nSubFrames */ - - - return AAC_ENC_OK; - -QCOutNew_bail: - return ErrorStatus; -} - -/********************************************************************************* - - functionname: FDKaacEnc_QCOutInit - description: - return: - -**********************************************************************************/ -AAC_ENCODER_ERROR FDKaacEnc_QCOutInit(QC_OUT *phQC[(1)], - const INT nSubFrames, - const CHANNEL_MAPPING *cm) -{ - INT n,i,ch; - - for (n=0; n<nSubFrames; n++) { - INT chInc = 0; - for (i=0; i<cm->nElements; i++) { - for (ch=0; ch<cm->elInfo[i].nChannelsInEl; ch++) { - phQC[n]->qcElement[i]->qcOutChannel[ch] = phQC[n]->pQcOutChannels[chInc]; - chInc++; - } /* chInEl */ - } /* nElements */ - } /* nSubFrames */ - - return AAC_ENC_OK; -} - -/********************************************************************************* - - functionname: FDKaacEnc_QCNew - description: - return: - -**********************************************************************************/ -AAC_ENCODER_ERROR FDKaacEnc_QCNew(QC_STATE **phQC, - INT nElements - ,UCHAR* dynamic_RAM - ) -{ - AAC_ENCODER_ERROR ErrorStatus; - int i; - - QC_STATE* hQC = GetRam_aacEnc_QCstate(); - *phQC = hQC; - if (hQC == NULL) { - ErrorStatus = AAC_ENC_NO_MEMORY; - goto QCNew_bail; - } - - if (FDKaacEnc_AdjThrNew(&hQC->hAdjThr, nElements)) { - ErrorStatus = AAC_ENC_NO_MEMORY; - goto QCNew_bail; - } - - if (FDKaacEnc_BCNew(&(hQC->hBitCounter), dynamic_RAM)) { - ErrorStatus = AAC_ENC_NO_MEMORY; - goto QCNew_bail; - } - - for (i=0; i<nElements; i++) { - hQC->elementBits[i] = GetRam_aacEnc_ElementBits(i); - if (hQC->elementBits[i] == NULL) { - ErrorStatus = AAC_ENC_NO_MEMORY; - goto QCNew_bail; - } - } - - return AAC_ENC_OK; - -QCNew_bail: - FDKaacEnc_QCClose(phQC, NULL); - return ErrorStatus; -} - -/********************************************************************************* - - functionname: FDKaacEnc_QCInit - description: - return: - -**********************************************************************************/ -AAC_ENCODER_ERROR FDKaacEnc_QCInit(QC_STATE *hQC, - struct QC_INIT *init) -{ - hQC->maxBitsPerFrame = init->maxBits; - hQC->minBitsPerFrame = init->minBits; - hQC->nElements = init->channelMapping->nElements; - hQC->bitResTotMax = init->bitRes; - hQC->bitResTot = init->bitRes; - hQC->maxBitFac = init->maxBitFac; - hQC->bitrateMode = init->bitrateMode; - hQC->invQuant = init->invQuant; - hQC->maxIterations = init->maxIterations; - - if ( isConstantBitrateMode(hQC->bitrateMode) ) { - INT bitresPerChannel = (hQC->bitResTotMax / init->channelMapping->nChannelsEff); - /* 0: full bitreservoir, 1: reduced bitreservoir, 2: disabled bitreservoir */ - hQC->bitDistributionMode = (bitresPerChannel>100) ? 0 : (bitresPerChannel>0) ? 1 : 2; - } - else { - hQC->bitDistributionMode = 0; /* full bitreservoir */ - } - - - hQC->padding.paddingRest = init->padding.paddingRest; - - hQC->globHdrBits = init->staticBits; /* Bit overhead due to transport */ - - FDKaacEnc_InitElementBits(hQC, - init->channelMapping, - init->bitrate, - (init->averageBits/init->nSubFrames) - hQC->globHdrBits, - hQC->maxBitsPerFrame/init->channelMapping->nChannelsEff); - - switch(hQC->bitrateMode){ - case QCDATA_BR_MODE_CBR: - case QCDATA_BR_MODE_VBR_1: - case QCDATA_BR_MODE_VBR_2: - case QCDATA_BR_MODE_VBR_3: - case QCDATA_BR_MODE_VBR_4: - case QCDATA_BR_MODE_VBR_5: - case QCDATA_BR_MODE_SFR: - case QCDATA_BR_MODE_FF: - if((int)hQC->bitrateMode < (int)(sizeof(tableVbrQualFactor)/sizeof(TAB_VBR_QUAL_FACTOR))){ - hQC->vbrQualFactor = (FIXP_DBL)tableVbrQualFactor[hQC->bitrateMode].vbrQualFactor; - } else { - hQC->vbrQualFactor = FL2FXCONST_DBL(0.f); /* default setting */ - } - break; - case QCDATA_BR_MODE_INVALID: - default: - hQC->vbrQualFactor = FL2FXCONST_DBL(0.f); - break; - } - - FDKaacEnc_AdjThrInit( - hQC->hAdjThr, - init->meanPe, - hQC->elementBits, /* or channelBitrates, was: channelBitrate */ - hQC->invQuant, - init->channelMapping->nElements, - init->channelMapping->nChannelsEff, - init->sampleRate, /* output sample rate */ - init->advancedBitsToPe, /* if set, calc bits2PE factor depending on samplerate */ - hQC->vbrQualFactor - ); - - return AAC_ENC_OK; -} - - - -/********************************************************************************* - - functionname: FDKaacEnc_QCMainPrepare - description: - return: - -**********************************************************************************/ -AAC_ENCODER_ERROR FDKaacEnc_QCMainPrepare(ELEMENT_INFO *elInfo, - ATS_ELEMENT* RESTRICT adjThrStateElement, - PSY_OUT_ELEMENT* RESTRICT psyOutElement, - QC_OUT_ELEMENT* RESTRICT qcOutElement, - AUDIO_OBJECT_TYPE aot, - UINT syntaxFlags, - SCHAR epConfig - ) -{ - AAC_ENCODER_ERROR ErrorStatus = AAC_ENC_OK; - INT nChannels = elInfo->nChannelsInEl; - - PSY_OUT_CHANNEL** RESTRICT psyOutChannel = psyOutElement->psyOutChannel; /* may be modified in-place */ - - FDKaacEnc_CalcFormFactor(qcOutElement->qcOutChannel, psyOutChannel, nChannels); - - /* prepare and calculate PE without reduction */ - FDKaacEnc_peCalculation(&qcOutElement->peData, psyOutChannel, qcOutElement->qcOutChannel, &psyOutElement->toolsInfo, adjThrStateElement, nChannels); - - ErrorStatus = FDKaacEnc_ChannelElementWrite( NULL, elInfo, NULL, - psyOutElement, - psyOutElement->psyOutChannel, - syntaxFlags, - aot, - epConfig, - &qcOutElement->staticBitsUsed, - 0 ); - - return ErrorStatus; -} - -/********************************************************************************* - - functionname: FDKaacEnc_AdjustBitrate - description: adjusts framelength via padding on a frame to frame basis, - to achieve a bitrate that demands a non byte aligned - framelength - return: errorcode - -**********************************************************************************/ -AAC_ENCODER_ERROR FDKaacEnc_AdjustBitrate(QC_STATE *RESTRICT hQC, - CHANNEL_MAPPING *RESTRICT cm, - INT *avgTotalBits, - INT bitRate, /* total bitrate */ - INT sampleRate, /* output sampling rate */ - INT granuleLength) /* frame length */ -{ - INT paddingOn=0; - INT frameLen; - //fprintf(stderr, "hQC->padding.paddingRest=%d bytes! (before)\n", hQC->padding.paddingRest); - - /* Do we need an extra padding byte? */ - paddingOn = FDKaacEnc_framePadding(bitRate, - sampleRate, - granuleLength, - &hQC->padding.paddingRest); - //fprintf(stderr, "hQC->padding.paddingRest=%d bytes! (after)\n", hQC->padding.paddingRest); - - frameLen = paddingOn + FDKaacEnc_calcFrameLen(bitRate, - sampleRate, - granuleLength, - FRAME_LEN_BYTES_INT); - - //fprintf(stderr, "frameLen=%d bytes!\n", frameLen); - - *avgTotalBits = frameLen<<3; - - return AAC_ENC_OK; -} - -static AAC_ENCODER_ERROR FDKaacEnc_distributeElementDynBits(QC_STATE* hQC, - QC_OUT_ELEMENT* qcElement[(8)], - CHANNEL_MAPPING* cm, - INT codeBits) -{ - - INT i, firstEl = cm->nElements-1; - INT totalBits = 0; - - for (i=(cm->nElements-1); i>=0; i--) { - if ((cm->elInfo[i].elType == ID_SCE) || (cm->elInfo[i].elType == ID_CPE) || - (cm->elInfo[i].elType == ID_LFE)) - { - qcElement[i]->grantedDynBits = (INT)fMult(hQC->elementBits[i]->relativeBitsEl, (FIXP_DBL)codeBits); - totalBits += qcElement[i]->grantedDynBits; - firstEl = i; - } - } - qcElement[firstEl]->grantedDynBits += codeBits - totalBits; - - return AAC_ENC_OK; -} - -/** - * \brief Verify whether minBitsPerFrame criterion can be satisfied. - * - * This function evaluates the bit consumption only if minBitsPerFrame parameter is not 0. - * In hyperframing mode the difference between grantedDynBits and usedDynBits of all sub frames - * results the number of fillbits to be written. - * This bits can be distrubitued in superframe to reach minBitsPerFrame bit consumption in single AU's. - * The return value denotes if enough desired fill bits are available to achieve minBitsPerFrame in all frames. - * This check can only be used within superframes. - * - * \param qcOut Pointer to coding data struct. - * \param minBitsPerFrame Minimal number of bits to be consumed in each frame. - * \param nSubFrames Number of frames in superframe - * - * \return - * - 1: all fine - * - 0: criterion not fulfilled - */ -static int checkMinFrameBitsDemand( - QC_OUT** qcOut, - const INT minBitsPerFrame, - const INT nSubFrames - ) -{ - int result = 1; /* all fine*/ - return result; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -/********************************************************************************* - - functionname: FDKaacEnc_getMinimalStaticBitdemand - description: calculate minmal size of static bits by reduction , - to zero spectrum and deactivating tns and MS - return: number of static bits - -**********************************************************************************/ -static int FDKaacEnc_getMinimalStaticBitdemand(CHANNEL_MAPPING* cm, - PSY_OUT** psyOut) -{ - AUDIO_OBJECT_TYPE aot = AOT_AAC_LC; - UINT syntaxFlags = 0; - SCHAR epConfig = -1; - int i, bitcount = 0; - - for (i=0; i<cm->nElements; i++) { - ELEMENT_INFO elInfo = cm->elInfo[i]; - - if ( (elInfo.elType == ID_SCE) - || (elInfo.elType == ID_CPE) - || (elInfo.elType == ID_LFE) ) - { - INT minElBits = 0; - - FDKaacEnc_ChannelElementWrite( NULL, &elInfo, NULL, - psyOut[0]->psyOutElement[i], - psyOut[0]->psyOutElement[i]->psyOutChannel, - syntaxFlags, - aot, - epConfig, - &minElBits, - 1 ); - bitcount += minElBits; - } - } - - return bitcount; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -static AAC_ENCODER_ERROR FDKaacEnc_prepareBitDistribution(QC_STATE* hQC, - PSY_OUT** psyOut, - QC_OUT** qcOut, - CHANNEL_MAPPING* cm, - QC_OUT_ELEMENT* qcElement[(1)][(8)], - INT avgTotalBits, - INT *totalAvailableBits, - INT *avgTotalDynBits) -{ - int i; - /* get maximal allowed dynamic bits */ - qcOut[0]->grantedDynBits = (fixMin(hQC->maxBitsPerFrame, avgTotalBits) - hQC->globHdrBits)&~7; - qcOut[0]->grantedDynBits -= (qcOut[0]->globalExtBits + qcOut[0]->staticBits + qcOut[0]->elementExtBits); - qcOut[0]->maxDynBits = ((hQC->maxBitsPerFrame)&~7) - (qcOut[0]->globalExtBits + qcOut[0]->staticBits + qcOut[0]->elementExtBits); - /* assure that enough bits are available */ - if ((qcOut[0]->grantedDynBits+hQC->bitResTot) < 0) { - /* crash recovery allows to reduce static bits to a minimum */ - if ( (qcOut[0]->grantedDynBits+hQC->bitResTot) < (FDKaacEnc_getMinimalStaticBitdemand(cm, psyOut)-qcOut[0]->staticBits) ) - return AAC_ENC_BITRES_TOO_LOW; - } - - /* distribute dynamic bits to each element */ - FDKaacEnc_distributeElementDynBits(hQC, - qcElement[0], - cm, - qcOut[0]->grantedDynBits); - - *avgTotalDynBits = 0; /*frameDynBits;*/ - - *totalAvailableBits = avgTotalBits; - - /* sum up corrected granted PE */ - qcOut[0]->totalGrantedPeCorr = 0; - - for (i=0; i<cm->nElements; i++) - { - ELEMENT_INFO elInfo = cm->elInfo[i]; - int nChannels = elInfo.nChannelsInEl; - - if ((elInfo.elType == ID_SCE) || (elInfo.elType == ID_CPE) || - (elInfo.elType == ID_LFE)) - { - /* for ( all sub frames ) ... */ - FDKaacEnc_DistributeBits(hQC->hAdjThr, - hQC->hAdjThr->adjThrStateElem[i], - psyOut[0]->psyOutElement[i]->psyOutChannel, - &qcElement[0][i]->peData, - &qcElement[0][i]->grantedPe, - &qcElement[0][i]->grantedPeCorr, - nChannels, - psyOut[0]->psyOutElement[i]->commonWindow, - qcElement[0][i]->grantedDynBits, - hQC->elementBits[i]->bitResLevelEl, - hQC->elementBits[i]->maxBitResBitsEl, - hQC->maxBitFac, - hQC->bitDistributionMode); - - *totalAvailableBits += hQC->elementBits[i]->bitResLevelEl; - /* get total corrected granted PE */ - qcOut[0]->totalGrantedPeCorr += qcElement[0][i]->grantedPeCorr; - } /* -end- if(ID_SCE || ID_CPE || ID_LFE) */ - - } /* -end- element loop */ - - *totalAvailableBits = FDKmin(hQC->maxBitsPerFrame, (*totalAvailableBits)); - - return AAC_ENC_OK; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -static AAC_ENCODER_ERROR FDKaacEnc_updateUsedDynBits(INT* sumDynBitsConsumed, - QC_OUT_ELEMENT* qcElement[(8)], - CHANNEL_MAPPING* cm) -{ - INT i; - - *sumDynBitsConsumed = 0; - - for (i=0; i<cm->nElements; i++) - { - ELEMENT_INFO elInfo = cm->elInfo[i]; - - if ((elInfo.elType == ID_SCE) || (elInfo.elType == ID_CPE) || - (elInfo.elType == ID_LFE)) - { - /* sum up bits consumed */ - *sumDynBitsConsumed += qcElement[i]->dynBitsUsed; - } /* -end- if(ID_SCE || ID_CPE || ID_LFE) */ - - } /* -end- element loop */ - - return AAC_ENC_OK; -} - - -static INT FDKaacEnc_getTotalConsumedDynBits(QC_OUT** qcOut, - INT nSubFrames) -{ - INT c, totalBits=0; - - /* sum up bit consumption for all sub frames */ - for (c=0; c<nSubFrames; c++) - { - /* bit consumption not valid if dynamic bits - not available in one sub frame */ - if (qcOut[c]->usedDynBits==-1) return -1; - totalBits += qcOut[c]->usedDynBits; - } - - return totalBits; - -} - -static INT FDKaacEnc_getTotalConsumedBits(QC_OUT** qcOut, - QC_OUT_ELEMENT* qcElement[(1)][(8)], - CHANNEL_MAPPING* cm, - INT globHdrBits, - INT nSubFrames) -{ - int c, i; - int totalUsedBits = 0; - - for (c = 0 ; c < nSubFrames ; c++ ) - { - int dataBits = 0; - for (i=0; i<cm->nElements; i++) - { - if ((cm->elInfo[i].elType == ID_SCE) || (cm->elInfo[i].elType == ID_CPE) || - (cm->elInfo[i].elType == ID_LFE)) - { - dataBits += qcElement[c][i]->dynBitsUsed + qcElement[c][i]->staticBitsUsed + qcElement[c][i]->extBitsUsed; - } - } - dataBits += qcOut[c]->globalExtBits; - - totalUsedBits += (8 - (dataBits) % 8) % 8; - totalUsedBits += dataBits + globHdrBits; /* header bits for every frame */ - } - return totalUsedBits; -} - -static AAC_ENCODER_ERROR FDKaacEnc_BitResRedistribution( - QC_STATE *const hQC, - const CHANNEL_MAPPING *const cm, - const INT avgTotalBits - ) -{ - /* check bitreservoir fill level */ - if (hQC->bitResTot < 0) { - return AAC_ENC_BITRES_TOO_LOW; - } - else if (hQC->bitResTot > hQC->bitResTotMax) { - return AAC_ENC_BITRES_TOO_HIGH; - } - else { - INT i, firstEl = cm->nElements-1; - INT totalBits = 0, totalBits_max = 0; - - int totalBitreservoir = FDKmin(hQC->bitResTot, (hQC->maxBitsPerFrame-avgTotalBits)); - int totalBitreservoirMax = FDKmin(hQC->bitResTotMax, (hQC->maxBitsPerFrame-avgTotalBits)); - - int sc_bitResTot = CountLeadingBits(totalBitreservoir); - int sc_bitResTotMax = CountLeadingBits(totalBitreservoirMax); - - for (i=(cm->nElements-1); i>=0; i--) { - if ((cm->elInfo[i].elType == ID_SCE) || (cm->elInfo[i].elType == ID_CPE) || - (cm->elInfo[i].elType == ID_LFE)) - { - hQC->elementBits[i]->bitResLevelEl = (INT)fMult(hQC->elementBits[i]->relativeBitsEl, (FIXP_DBL)(totalBitreservoir<<sc_bitResTot))>>sc_bitResTot; - totalBits += hQC->elementBits[i]->bitResLevelEl; - - hQC->elementBits[i]->maxBitResBitsEl = (INT)fMult(hQC->elementBits[i]->relativeBitsEl, (FIXP_DBL)(totalBitreservoirMax<<sc_bitResTotMax))>>sc_bitResTotMax; - totalBits_max += hQC->elementBits[i]->maxBitResBitsEl; - - firstEl = i; - } - } - hQC->elementBits[firstEl]->bitResLevelEl += totalBitreservoir - totalBits; - hQC->elementBits[firstEl]->maxBitResBitsEl += totalBitreservoirMax - totalBits_max; - } - - return AAC_ENC_OK; -} - - -AAC_ENCODER_ERROR FDKaacEnc_QCMain(QC_STATE* RESTRICT hQC, - PSY_OUT** psyOut, - QC_OUT** qcOut, - INT avgTotalBits, - CHANNEL_MAPPING* cm - ,AUDIO_OBJECT_TYPE aot, - UINT syntaxFlags, - SCHAR epConfig - ) -{ - int i, c; - AAC_ENCODER_ERROR ErrorStatus = AAC_ENC_OK; - INT avgTotalDynBits = 0; /* maximal allowed dynamic bits for all frames */ - INT totalAvailableBits = 0; - INT nSubFrames = 1; - - /*-------------------------------------------- */ - /* redistribute total bitreservoir to elements */ - ErrorStatus = FDKaacEnc_BitResRedistribution(hQC, cm, avgTotalBits); - if (ErrorStatus != AAC_ENC_OK) { - return ErrorStatus; - } - - /*-------------------------------------------- */ - /* fastenc needs one time threshold simulation, - in case of multiple frames, one more guess has to be calculated */ - - /*-------------------------------------------- */ - /* helper pointer */ - QC_OUT_ELEMENT* qcElement[(1)][(8)]; - - /* work on a copy of qcChannel and qcElement */ - for (i=0; i<cm->nElements; i++) - { - ELEMENT_INFO elInfo = cm->elInfo[i]; - - if ((elInfo.elType == ID_SCE) || (elInfo.elType == ID_CPE) || - (elInfo.elType == ID_LFE)) - { - /* for ( all sub frames ) ... */ - for (c = 0 ; c < nSubFrames ; c++ ) - { - { - qcElement[c][i] = qcOut[c]->qcElement[i]; - } - } - } - } - - /*-------------------------------------------- */ - /*-------------------------------------------- */ - if ( isConstantBitrateMode(hQC->bitrateMode) ) - { - /* calc granted dynamic bits for sub frame and - distribute it to each element */ - ErrorStatus = FDKaacEnc_prepareBitDistribution( - hQC, - psyOut, - qcOut, - cm, - qcElement, - avgTotalBits, - &totalAvailableBits, - &avgTotalDynBits); - - if (ErrorStatus != AAC_ENC_OK) { - return ErrorStatus; - } - } - else { - qcOut[0]->grantedDynBits = ((hQC->maxBitsPerFrame - (hQC->globHdrBits))&~7) - - (qcOut[0]->globalExtBits + qcOut[0]->staticBits + qcOut[0]->elementExtBits); - qcOut[0]->maxDynBits = qcOut[0]->grantedDynBits; - - totalAvailableBits = hQC->maxBitsPerFrame; - avgTotalDynBits = 0; - } - -#ifdef PNS_PRECOUNT_ENABLE - /* Calculate estimated pns bits and substract them from grantedDynBits to get a more accurate number of available bits. */ - if (syntaxFlags & (AC_LD|AC_ELD)) - { - int estimatedPnsBits = 0, ch; - - for (ch=0; ch<cm->nChannels; ch++) { - qcOut[0]->pQcOutChannels[ch]->sectionData.noiseNrgBits = noisePreCount(psyOut[0]->pPsyOutChannels[ch]->noiseNrg, psyOut[0]->pPsyOutChannels[ch]->maxSfbPerGroup); - estimatedPnsBits += qcOut[0]->pQcOutChannels[ch]->sectionData.noiseNrgBits; - } - qcOut[0]->grantedDynBits -= estimatedPnsBits; - } -#endif - - /* for ( all sub frames ) ... */ - for (c = 0 ; c < nSubFrames ; c++ ) - { - /* for CBR and VBR mode */ - FDKaacEnc_AdjustThresholds(hQC->hAdjThr->adjThrStateElem, - qcElement[c], - qcOut[c], - psyOut[c]->psyOutElement, - isConstantBitrateMode(hQC->bitrateMode), - cm); - - } /* -end- sub frame counter */ - - /*-------------------------------------------- */ - INT iterations[(1)][(8)]; - INT chConstraintsFulfilled[(1)][(8)][(2)]; - INT calculateQuant[(1)][(8)][(2)]; - INT constraintsFulfilled[(1)][(8)]; - /*-------------------------------------------- */ - - - /* for ( all sub frames ) ... */ - for (c = 0 ; c < nSubFrames ; c++ ) - { - for (i=0; i<cm->nElements; i++) - { - ELEMENT_INFO elInfo = cm->elInfo[i]; - INT ch, nChannels = elInfo.nChannelsInEl; - - if ((elInfo.elType == ID_SCE) || (elInfo.elType == ID_CPE) || - (elInfo.elType == ID_LFE)) - { - /* Turn thresholds into scalefactors, optimize bit consumption and verify conformance */ - FDKaacEnc_EstimateScaleFactors(psyOut[c]->psyOutElement[i]->psyOutChannel, - qcElement[c][i]->qcOutChannel, - hQC->invQuant, - cm->elInfo[i].nChannelsInEl); - - - /*-------------------------------------------- */ - constraintsFulfilled[c][i] = 1; - iterations[c][i] = 0 ; - - for (ch = 0; ch < nChannels; ch++) - { - chConstraintsFulfilled[c][i][ch] = 1; - calculateQuant[c][i][ch] = 1; - } - - /*-------------------------------------------- */ - - } /* -end- if(ID_SCE || ID_CPE || ID_LFE) */ - - } /* -end- element loop */ - - qcOut[c]->usedDynBits = -1; - - } /* -end- sub frame counter */ - - - - INT quantizationDone = 0; - INT sumDynBitsConsumedTotal = 0; - INT decreaseBitConsumption = -1; /* no direction yet! */ - - /*-------------------------------------------- */ - /* -start- Quantization loop ... */ - /*-------------------------------------------- */ - do /* until max allowed bits per frame and maxDynBits!=-1*/ - { - quantizationDone = 0; - - c = 0; /* get frame to process */ - - for (i=0; i<cm->nElements; i++) - { - ELEMENT_INFO elInfo = cm->elInfo[i]; - INT ch, nChannels = elInfo.nChannelsInEl; - - if ((elInfo.elType == ID_SCE) || (elInfo.elType == ID_CPE) || - (elInfo.elType == ID_LFE)) - { - do /* until spectral values < MAX_QUANT */ - { - /*-------------------------------------------- */ - if (!constraintsFulfilled[c][i]) - { - FDKaacEnc_reduceBitConsumption(&iterations[c][i], - hQC->maxIterations, - (decreaseBitConsumption) ? 1 : -1, - chConstraintsFulfilled[c][i], - calculateQuant[c][i], - nChannels, - psyOut[c]->psyOutElement[i], - qcOut[c], - qcElement[c][i], - hQC->elementBits[i], - aot, - syntaxFlags, - epConfig); - } - - /*-------------------------------------------- */ - /*-------------------------------------------- */ - constraintsFulfilled[c][i] = 1 ; - - /*-------------------------------------------- */ - /* quantize spectrum (per each channel) */ - for (ch = 0; ch < nChannels; ch++) - { - /*-------------------------------------------- */ - chConstraintsFulfilled[c][i][ch] = 1; - - /*-------------------------------------------- */ - - if (calculateQuant[c][i][ch]) - { - QC_OUT_CHANNEL* qcOutCh = qcElement[c][i]->qcOutChannel[ch]; - PSY_OUT_CHANNEL* psyOutCh = psyOut[c]->psyOutElement[i]->psyOutChannel[ch]; - - calculateQuant[c][i][ch] = 0; /* calculate quantization only if necessary */ - - /*-------------------------------------------- */ - FDKaacEnc_QuantizeSpectrum(psyOutCh->sfbCnt, - psyOutCh->maxSfbPerGroup, - psyOutCh->sfbPerGroup, - psyOutCh->sfbOffsets, - qcOutCh->mdctSpectrum, - qcOutCh->globalGain, - qcOutCh->scf, - qcOutCh->quantSpec) ; - - /*-------------------------------------------- */ - if (FDKaacEnc_calcMaxValueInSfb(psyOutCh->sfbCnt, - psyOutCh->maxSfbPerGroup, - psyOutCh->sfbPerGroup, - psyOutCh->sfbOffsets, - qcOutCh->quantSpec, - qcOutCh->maxValueInSfb) > MAX_QUANT) - { - chConstraintsFulfilled[c][i][ch] = 0; - constraintsFulfilled[c][i] = 0 ; - /* if quanizted value out of range; increase global gain! */ - decreaseBitConsumption = 1; - } - - /*-------------------------------------------- */ - - } /* if calculateQuant[c][i][ch] */ - - } /* channel loop */ - - /*-------------------------------------------- */ - /* quantize spectrum (per each channel) */ - - /*-------------------------------------------- */ - - } while (!constraintsFulfilled[c][i]) ; /* does not regard bit consumption */ - - - /*-------------------------------------------- */ - /*-------------------------------------------- */ - qcElement[c][i]->dynBitsUsed = 0 ; /* reset dynamic bits */ - - /* quantization valid in current channel! */ - for (ch = 0; ch < nChannels; ch++) - { - QC_OUT_CHANNEL* qcOutCh = qcElement[c][i]->qcOutChannel[ch]; - PSY_OUT_CHANNEL *psyOutCh = psyOut[c]->psyOutElement[i]->psyOutChannel[ch]; - - /* count dynamic bits */ - INT chDynBits = FDKaacEnc_dynBitCount(hQC->hBitCounter, - qcOutCh->quantSpec, - qcOutCh->maxValueInSfb, - qcOutCh->scf, - psyOutCh->lastWindowSequence, - psyOutCh->sfbCnt, - psyOutCh->maxSfbPerGroup, - psyOutCh->sfbPerGroup, - psyOutCh->sfbOffsets, - &qcOutCh->sectionData, - psyOutCh->noiseNrg, - psyOutCh->isBook, - psyOutCh->isScale, - syntaxFlags) ; - - /* sum up dynamic channel bits */ - qcElement[c][i]->dynBitsUsed += chDynBits; - } - - /* save dynBitsUsed for correction of bits2pe relation */ - if(hQC->hAdjThr->adjThrStateElem[i]->dynBitsLast==-1) { - hQC->hAdjThr->adjThrStateElem[i]->dynBitsLast = qcElement[c][i]->dynBitsUsed; - } - } /* -end- if(ID_SCE || ID_CPE || ID_LFE) */ - - } /* -end- element loop */ - - /* update dynBits of current subFrame */ - FDKaacEnc_updateUsedDynBits(&qcOut[c]->usedDynBits, - qcElement[c], - cm); - - /* get total consumed bits, dyn bits in all sub frames have to be valid */ - sumDynBitsConsumedTotal = FDKaacEnc_getTotalConsumedDynBits(qcOut, nSubFrames); - - if (sumDynBitsConsumedTotal==-1) - { - quantizationDone = 0; /* bit consumption not valid in all sub frames */ - } - else - { - int sumBitsConsumedTotal = FDKaacEnc_getTotalConsumedBits(qcOut, qcElement, cm, hQC->globHdrBits, nSubFrames); - - /* in all frames are valid dynamic bits */ - if ( ((sumBitsConsumedTotal < totalAvailableBits) || qcOut[c]->usedDynBits==0) && (decreaseBitConsumption==1) && checkMinFrameBitsDemand(qcOut,hQC->minBitsPerFrame,nSubFrames) - /*()*/ ) - { - quantizationDone = 1; /* exit bit adjustment */ - } - if (sumBitsConsumedTotal > totalAvailableBits && (decreaseBitConsumption==0) ) -// /*()*/ ) - { - quantizationDone = 0; /* reset! */ - break; - } - } - - - /*-------------------------------------------- */ - - int emergencyIterations = 1; - int dynBitsOvershoot = 0; - - for (c = 0 ; c < nSubFrames ; c++ ) - { - for (i=0; i<cm->nElements; i++) - { - ELEMENT_INFO elInfo = cm->elInfo[i]; - - if ((elInfo.elType == ID_SCE) || (elInfo.elType == ID_CPE) || - (elInfo.elType == ID_LFE)) - { - /* iteration limitation */ - emergencyIterations &= ((iterations[c][i] < hQC->maxIterations) ? 0 : 1); - } - } - /* detection if used dyn bits exceeds the maximal allowed criterion */ - dynBitsOvershoot |= ((qcOut[c]->usedDynBits > qcOut[c]->maxDynBits) ? 1 : 0); - } - - if (quantizationDone==0 || dynBitsOvershoot) - { - - int sumBitsConsumedTotal = FDKaacEnc_getTotalConsumedBits(qcOut, qcElement, cm, hQC->globHdrBits, nSubFrames); - - if ( (sumDynBitsConsumedTotal >= avgTotalDynBits) || (sumDynBitsConsumedTotal==0) ) { - quantizationDone = 1; - } - if (emergencyIterations && (sumBitsConsumedTotal < totalAvailableBits)) { - quantizationDone = 1; - } - if ((sumBitsConsumedTotal > totalAvailableBits) || !checkMinFrameBitsDemand(qcOut,hQC->minBitsPerFrame,nSubFrames)) { - quantizationDone = 0; - } - if ((sumBitsConsumedTotal < totalAvailableBits) && checkMinFrameBitsDemand(qcOut,hQC->minBitsPerFrame,nSubFrames)) { - decreaseBitConsumption = 0; - } - else { - decreaseBitConsumption = 1; - } - - if (dynBitsOvershoot) { - quantizationDone = 0; - decreaseBitConsumption = 1; - } - - /* reset constraints fullfilled flags */ - FDKmemclear(constraintsFulfilled, sizeof(constraintsFulfilled)); - FDKmemclear(chConstraintsFulfilled, sizeof(chConstraintsFulfilled)); - - - }/* quantizationDone */ - - } while (!quantizationDone) ; - - /*-------------------------------------------- */ - /* ... -end- Quantization loop */ - /*-------------------------------------------- */ - - /*-------------------------------------------- */ - /*-------------------------------------------- */ - - return AAC_ENC_OK; -} - - -static AAC_ENCODER_ERROR FDKaacEnc_reduceBitConsumption(int* iterations, - const int maxIterations, - int gainAdjustment, - int* chConstraintsFulfilled, - int* calculateQuant, - int nChannels, - PSY_OUT_ELEMENT* psyOutElement, - QC_OUT* qcOut, - QC_OUT_ELEMENT* qcOutElement, - ELEMENT_BITS* elBits, - AUDIO_OBJECT_TYPE aot, - UINT syntaxFlags, - SCHAR epConfig) -{ - int ch; - - /** SOLVING PROBLEM **/ - if ((*iterations)++ >= maxIterations) - { - if (qcOutElement->dynBitsUsed==0) { - } - /* crash recovery */ - else { - INT bitsToSave = 0; - if ( (bitsToSave = fixMax((qcOutElement->dynBitsUsed + 8) - (elBits->bitResLevelEl + qcOutElement->grantedDynBits), - (qcOutElement->dynBitsUsed + qcOutElement->staticBitsUsed + 8) - (elBits->maxBitsEl))) > 0 ) - { - FDKaacEnc_crashRecovery(nChannels, - psyOutElement, - qcOut, - qcOutElement, - bitsToSave, - aot, - syntaxFlags, - epConfig) ; - } - else - { - for (ch = 0; ch < nChannels; ch++) - { - qcOutElement->qcOutChannel[ch]->globalGain += 1; - } - } - for (ch = 0; ch < nChannels; ch++) - { - calculateQuant[ch] = 1; - } - } - } - else /* iterations >= maxIterations */ - { - /* increase gain (+ next iteration) */ - for (ch = 0; ch < nChannels; ch++) - { - if(!chConstraintsFulfilled[ch]) - { - qcOutElement->qcOutChannel[ch]->globalGain += gainAdjustment ; - calculateQuant[ch] = 1; /* global gain has changed, recalculate quantization in next iteration! */ - } - } - } - - return AAC_ENC_OK; -} - -AAC_ENCODER_ERROR FDKaacEnc_updateFillBits(CHANNEL_MAPPING* cm, - QC_STATE* qcKernel, - ELEMENT_BITS* RESTRICT elBits[(8)], - QC_OUT** qcOut) -{ - switch (qcKernel->bitrateMode) { - case QCDATA_BR_MODE_SFR: - break; - - case QCDATA_BR_MODE_FF: - break; - - case QCDATA_BR_MODE_VBR_1: - case QCDATA_BR_MODE_VBR_2: - case QCDATA_BR_MODE_VBR_3: - case QCDATA_BR_MODE_VBR_4: - case QCDATA_BR_MODE_VBR_5: - qcOut[0]->totFillBits = (qcOut[0]->grantedDynBits - qcOut[0]->usedDynBits)&7; /* precalculate alignment bits */ - break; - - case QCDATA_BR_MODE_CBR: - case QCDATA_BR_MODE_INVALID: - default: - INT bitResSpace = qcKernel->bitResTotMax - qcKernel->bitResTot ; - /* processing fill-bits */ - INT deltaBitRes = qcOut[0]->grantedDynBits - qcOut[0]->usedDynBits ; - qcOut[0]->totFillBits = fixMax((deltaBitRes&7), (deltaBitRes - (fixMax(0,bitResSpace-7)&~7))); - break; - } /* switch (qcKernel->bitrateMode) */ - - return AAC_ENC_OK; -} - - - - -/********************************************************************************* - - functionname: FDKaacEnc_calcMaxValueInSfb - description: - return: - -**********************************************************************************/ - -static INT FDKaacEnc_calcMaxValueInSfb(INT sfbCnt, - INT maxSfbPerGroup, - INT sfbPerGroup, - INT *RESTRICT sfbOffset, - SHORT *RESTRICT quantSpectrum, - UINT *RESTRICT maxValue) -{ - INT sfbOffs,sfb; - INT maxValueAll = 0; - - for (sfbOffs=0;sfbOffs<sfbCnt;sfbOffs+=sfbPerGroup) - for (sfb = 0; sfb < maxSfbPerGroup; sfb++) - { - INT line; - INT maxThisSfb = 0; - for (line = sfbOffset[sfbOffs+sfb]; line < sfbOffset[sfbOffs+sfb+1]; line++) - { - INT tmp = fixp_abs(quantSpectrum[line]); - maxThisSfb = fixMax(tmp, maxThisSfb); - } - - maxValue[sfbOffs+sfb] = maxThisSfb; - maxValueAll = fixMax(maxThisSfb, maxValueAll); - } - return maxValueAll; -} - - -/********************************************************************************* - - functionname: FDKaacEnc_updateBitres - description: - return: - -**********************************************************************************/ -void FDKaacEnc_updateBitres(CHANNEL_MAPPING *cm, - QC_STATE* qcKernel, - QC_OUT** qcOut) -{ - switch (qcKernel->bitrateMode) { - case QCDATA_BR_MODE_FF: - case QCDATA_BR_MODE_VBR_1: - case QCDATA_BR_MODE_VBR_2: - case QCDATA_BR_MODE_VBR_3: - case QCDATA_BR_MODE_VBR_4: - case QCDATA_BR_MODE_VBR_5: - /* variable bitrate */ - qcKernel->bitResTot = FDKmin(qcKernel->maxBitsPerFrame, qcKernel->bitResTotMax); - break; - - case QCDATA_BR_MODE_CBR: - case QCDATA_BR_MODE_SFR: - case QCDATA_BR_MODE_INVALID: - default: - int c = 0; - /* constant bitrate */ - { - qcKernel->bitResTot += qcOut[c]->grantedDynBits - (qcOut[c]->usedDynBits + qcOut[c]->totFillBits + qcOut[c]->alignBits); - } - break; - } -} - -/********************************************************************************* - - functionname: FDKaacEnc_FinalizeBitConsumption - description: - return: - -**********************************************************************************/ -AAC_ENCODER_ERROR FDKaacEnc_FinalizeBitConsumption(CHANNEL_MAPPING *cm, - QC_STATE *qcKernel, - QC_OUT *qcOut, - QC_OUT_ELEMENT** qcElement, - HANDLE_TRANSPORTENC hTpEnc, - AUDIO_OBJECT_TYPE aot, - UINT syntaxFlags, - SCHAR epConfig) -{ - QC_OUT_EXTENSION fillExtPayload; - INT totFillBits, alignBits; - - /* Get total consumed bits in AU */ - qcOut->totalBits = qcOut->staticBits + qcOut->usedDynBits + qcOut->totFillBits + - qcOut->elementExtBits + qcOut->globalExtBits; -#if 1 - if (qcKernel->bitrateMode==QCDATA_BR_MODE_CBR) { - - /* Now we can get the exact transport bit amount, and hopefully it is equal to the estimated value */ - INT exactTpBits = transportEnc_GetStaticBits(hTpEnc, qcOut->totalBits); - - if (exactTpBits != qcKernel->globHdrBits) { - INT diffFillBits = 0; - - /* How many bits can be taken by bitreservoir */ - const INT bitresSpace = qcKernel->bitResTotMax - (qcKernel->bitResTot + (qcOut->grantedDynBits - (qcOut->usedDynBits + qcOut->totFillBits) ) ); - - /* Number of bits which can be moved to bitreservoir. */ - const INT bitsToBitres = qcKernel->globHdrBits - exactTpBits; - FDK_ASSERT(bitsToBitres>=0); /* is always positive */ - - /* If bitreservoir can not take all bits, move ramaining bits to fillbits */ - diffFillBits = FDKmax(0, bitsToBitres - bitresSpace); - - /* Assure previous alignment */ - diffFillBits = (diffFillBits+7)&~7; - - /* Move as many bits as possible to bitreservoir */ - qcKernel->bitResTot += (bitsToBitres-diffFillBits); - - /* Write remaing bits as fill bits */ - qcOut->totFillBits += diffFillBits; - qcOut->totalBits += diffFillBits; - qcOut->grantedDynBits += diffFillBits; - - /* Get new header bits */ - qcKernel->globHdrBits = transportEnc_GetStaticBits(hTpEnc, qcOut->totalBits); - - if (qcKernel->globHdrBits != exactTpBits) { - /* In previous step, fill bits and corresponding total bits were changed when bitreservoir was completely filled. - Now we can take the too much taken bits caused by header overhead from bitreservoir. - */ - qcKernel->bitResTot -= (qcKernel->globHdrBits - exactTpBits); - } - } - - } /* MODE_CBR */ -#endif - /* Update exact number of consumed header bits. */ - qcKernel->globHdrBits = transportEnc_GetStaticBits(hTpEnc, qcOut->totalBits); - - /* Save total fill bits and distribut to alignment and fill bits */ - totFillBits = qcOut->totFillBits; - - /* fake a fill extension payload */ - FDKmemclear(&fillExtPayload, sizeof(QC_OUT_EXTENSION)); - - fillExtPayload.type = EXT_FILL_DATA; - fillExtPayload.nPayloadBits = totFillBits; - - /* ask bitstream encoder how many of that bits can be written in a fill extension data entity */ - qcOut->totFillBits = FDKaacEnc_writeExtensionData( NULL, - &fillExtPayload, - 0, 0, - syntaxFlags, - aot, - epConfig ); - - //fprintf(stderr, "FinalizeBitConsumption(): totFillBits=%d, qcOut->totFillBits=%d \n", totFillBits, qcOut->totFillBits); - - /* now distribute extra fillbits and alignbits */ - alignBits = 7 - (qcOut->staticBits + qcOut->usedDynBits + qcOut->elementExtBits - + qcOut->totFillBits + qcOut->globalExtBits -1)%8; - - /* Maybe we could remove this */ - if( ((alignBits + qcOut->totFillBits - totFillBits)==8) && (qcOut->totFillBits>8) ) - qcOut->totFillBits -= 8; - - qcOut->totalBits = qcOut->staticBits + qcOut->usedDynBits + qcOut->totFillBits + - alignBits + qcOut->elementExtBits + qcOut->globalExtBits; - - if ( (qcOut->totalBits>qcKernel->maxBitsPerFrame) || (qcOut->totalBits<qcKernel->minBitsPerFrame) ) { - return AAC_ENC_QUANT_ERROR; - } - - qcOut->alignBits = alignBits; - - return AAC_ENC_OK; -} - - - -/********************************************************************************* - - functionname: FDKaacEnc_crashRecovery - description: fulfills constraints by means of brute force... - => bits are saved by cancelling out spectral lines!! - (beginning at the highest frequencies) - return: errorcode - -**********************************************************************************/ - -static void FDKaacEnc_crashRecovery(INT nChannels, - PSY_OUT_ELEMENT* psyOutElement, - QC_OUT* qcOut, - QC_OUT_ELEMENT *qcElement, - INT bitsToSave, - AUDIO_OBJECT_TYPE aot, - UINT syntaxFlags, - SCHAR epConfig) -{ - INT ch ; - INT savedBits = 0 ; - INT sfb, sfbGrp ; - INT bitsPerScf[(2)][MAX_GROUPED_SFB] ; - INT sectionToScf[(2)][MAX_GROUPED_SFB] ; - INT *sfbOffset ; - INT sect, statBitsNew ; - QC_OUT_CHANNEL **qcChannel = qcElement->qcOutChannel; - PSY_OUT_CHANNEL **psyChannel = psyOutElement->psyOutChannel; - - /* create a table which converts frq-bins to bit-demand... [bitsPerScf] */ - /* ...and another one which holds the corresponding sections [sectionToScf] */ - for (ch = 0; ch < nChannels; ch++) - { - sfbOffset = psyChannel[ch]->sfbOffsets ; - - for (sect = 0; sect < qcChannel[ch]->sectionData.noOfSections; sect++) - { - INT sfb ; - INT codeBook = qcChannel[ch]->sectionData.huffsection[sect].codeBook ; - - for (sfb = qcChannel[ch]->sectionData.huffsection[sect].sfbStart; - sfb < qcChannel[ch]->sectionData.huffsection[sect].sfbStart + - qcChannel[ch]->sectionData.huffsection[sect].sfbCnt; - sfb++) - { - bitsPerScf[ch][sfb] = 0; - if ( (codeBook != CODE_BOOK_PNS_NO) /*&& - (sfb < (qcChannel[ch]->sectionData.noOfGroups*qcChannel[ch]->sectionData.maxSfbPerGroup))*/ ) - { - INT sfbStartLine = sfbOffset[sfb] ; - INT noOfLines = sfbOffset[sfb+1] - sfbStartLine ; - bitsPerScf[ch][sfb] = FDKaacEnc_countValues(&(qcChannel[ch]->quantSpec[sfbStartLine]), noOfLines, codeBook) ; - } - sectionToScf[ch][sfb] = sect ; - } - - } - } - - /* LOWER [maxSfb] IN BOTH CHANNELS!! */ - /* Attention: in case of stereo: maxSfbL == maxSfbR, GroupingL == GroupingR ; */ - - for (sfb = qcChannel[0]->sectionData.maxSfbPerGroup-1; sfb >= 0; sfb--) - { - for (sfbGrp = 0; sfbGrp < psyChannel[0]->sfbCnt; sfbGrp += psyChannel[0]->sfbPerGroup) - { - for (ch = 0; ch < nChannels; ch++) - { - int sect = sectionToScf[ch][sfbGrp+sfb]; - qcChannel[ch]->sectionData.huffsection[sect].sfbCnt-- ; - savedBits += bitsPerScf[ch][sfbGrp+sfb] ; - - if (qcChannel[ch]->sectionData.huffsection[sect].sfbCnt == 0) { - savedBits += (psyChannel[ch]->lastWindowSequence!=SHORT_WINDOW) ? FDKaacEnc_sideInfoTabLong[0] - : FDKaacEnc_sideInfoTabShort[0]; - } - } - } - - /* ...have enough bits been saved? */ - if (savedBits >= bitsToSave) - break ; - - } /* sfb loop */ - - /* if not enough bits saved, - clean whole spectrum and remove side info overhead */ - if (sfb == -1) { - sfb = 0 ; - } - - for (ch = 0; ch < nChannels; ch++) - { - qcChannel[ch]->sectionData.maxSfbPerGroup = sfb ; - psyChannel[ch]->maxSfbPerGroup = sfb ; - /* when no spectrum is coded save tools info in bitstream */ - if(sfb==0) { - FDKmemclear(&psyChannel[ch]->tnsInfo, sizeof(TNS_INFO)); - FDKmemclear(&psyOutElement->toolsInfo, sizeof(TOOLSINFO)); - } - } - /* dynamic bits will be updated in iteration loop */ - - { /* if stop sfb has changed save bits in side info, e.g. MS or TNS coding */ - ELEMENT_INFO elInfo; - - FDKmemclear(&elInfo, sizeof(ELEMENT_INFO)); - elInfo.nChannelsInEl = nChannels; - elInfo.elType = (nChannels == 2) ? ID_CPE : ID_SCE; - - FDKaacEnc_ChannelElementWrite( NULL, &elInfo, NULL, - psyOutElement, - psyChannel, - syntaxFlags, - aot, - epConfig, - &statBitsNew, - 0 ); - } - - savedBits = qcElement->staticBitsUsed - statBitsNew; - - /* update static and dynamic bits */ - qcElement->staticBitsUsed -= savedBits; - qcElement->grantedDynBits += savedBits; - - qcOut->staticBits -= savedBits; - qcOut->grantedDynBits += savedBits; - qcOut->maxDynBits += savedBits; - - -} - - - -void FDKaacEnc_QCClose (QC_STATE **phQCstate, QC_OUT **phQC) -{ - int n, i; - - if (phQC!=NULL) { - - for (n=0;n<(1);n++) { - if (phQC[n] != NULL) { - QC_OUT *hQC = phQC[n]; - for (i=0; i<(8); i++) { - } - - for (i=0; i<(8); i++) { - if (hQC->qcElement[i]) - FreeRam_aacEnc_QCelement(&hQC->qcElement[i]); - } - - FreeRam_aacEnc_QCout(&phQC[n]); - } - } - } - - if (phQCstate!=NULL) { - if (*phQCstate != NULL) { - QC_STATE *hQCstate = *phQCstate; - - if (hQCstate->hAdjThr != NULL) - FDKaacEnc_AdjThrClose(&hQCstate->hAdjThr); - - if (hQCstate->hBitCounter != NULL) - FDKaacEnc_BCClose(&hQCstate->hBitCounter); - - for (i=0; i<(8); i++) { - if (hQCstate->elementBits[i]!=NULL) { - FreeRam_aacEnc_ElementBits(&hQCstate->elementBits[i]); - } - } - FreeRam_aacEnc_QCstate(phQCstate); - } - } -} - |