xref: /aosp_15_r20/external/aac/libAACenc/src/qc_main.cpp (revision e54365361535b070c2db7374cec45c159c7d0e7a)
1*e5436536SAndroid Build Coastguard Worker /* -----------------------------------------------------------------------------
2*e5436536SAndroid Build Coastguard Worker Software License for The Fraunhofer FDK AAC Codec Library for Android
3*e5436536SAndroid Build Coastguard Worker 
4*e5436536SAndroid Build Coastguard Worker © Copyright  1995 - 2020 Fraunhofer-Gesellschaft zur Förderung der angewandten
5*e5436536SAndroid Build Coastguard Worker Forschung e.V. All rights reserved.
6*e5436536SAndroid Build Coastguard Worker 
7*e5436536SAndroid Build Coastguard Worker  1.    INTRODUCTION
8*e5436536SAndroid Build Coastguard Worker The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
9*e5436536SAndroid Build Coastguard Worker that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
10*e5436536SAndroid Build Coastguard Worker scheme for digital audio. This FDK AAC Codec software is intended to be used on
11*e5436536SAndroid Build Coastguard Worker a wide variety of Android devices.
12*e5436536SAndroid Build Coastguard Worker 
13*e5436536SAndroid Build Coastguard Worker AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
14*e5436536SAndroid Build Coastguard Worker general perceptual audio codecs. AAC-ELD is considered the best-performing
15*e5436536SAndroid Build Coastguard Worker full-bandwidth communications codec by independent studies and is widely
16*e5436536SAndroid Build Coastguard Worker deployed. AAC has been standardized by ISO and IEC as part of the MPEG
17*e5436536SAndroid Build Coastguard Worker specifications.
18*e5436536SAndroid Build Coastguard Worker 
19*e5436536SAndroid Build Coastguard Worker Patent licenses for necessary patent claims for the FDK AAC Codec (including
20*e5436536SAndroid Build Coastguard Worker those of Fraunhofer) may be obtained through Via Licensing
21*e5436536SAndroid Build Coastguard Worker (www.vialicensing.com) or through the respective patent owners individually for
22*e5436536SAndroid Build Coastguard Worker the purpose of encoding or decoding bit streams in products that are compliant
23*e5436536SAndroid Build Coastguard Worker with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
24*e5436536SAndroid Build Coastguard Worker Android devices already license these patent claims through Via Licensing or
25*e5436536SAndroid Build Coastguard Worker directly from the patent owners, and therefore FDK AAC Codec software may
26*e5436536SAndroid Build Coastguard Worker already be covered under those patent licenses when it is used for those
27*e5436536SAndroid Build Coastguard Worker licensed purposes only.
28*e5436536SAndroid Build Coastguard Worker 
29*e5436536SAndroid Build Coastguard Worker Commercially-licensed AAC software libraries, including floating-point versions
30*e5436536SAndroid Build Coastguard Worker with enhanced sound quality, are also available from Fraunhofer. Users are
31*e5436536SAndroid Build Coastguard Worker encouraged to check the Fraunhofer website for additional applications
32*e5436536SAndroid Build Coastguard Worker information and documentation.
33*e5436536SAndroid Build Coastguard Worker 
34*e5436536SAndroid Build Coastguard Worker 2.    COPYRIGHT LICENSE
35*e5436536SAndroid Build Coastguard Worker 
36*e5436536SAndroid Build Coastguard Worker Redistribution and use in source and binary forms, with or without modification,
37*e5436536SAndroid Build Coastguard Worker are permitted without payment of copyright license fees provided that you
38*e5436536SAndroid Build Coastguard Worker satisfy the following conditions:
39*e5436536SAndroid Build Coastguard Worker 
40*e5436536SAndroid Build Coastguard Worker You must retain the complete text of this software license in redistributions of
41*e5436536SAndroid Build Coastguard Worker the FDK AAC Codec or your modifications thereto in source code form.
42*e5436536SAndroid Build Coastguard Worker 
43*e5436536SAndroid Build Coastguard Worker You must retain the complete text of this software license in the documentation
44*e5436536SAndroid Build Coastguard Worker and/or other materials provided with redistributions of the FDK AAC Codec or
45*e5436536SAndroid Build Coastguard Worker your modifications thereto in binary form. You must make available free of
46*e5436536SAndroid Build Coastguard Worker charge copies of the complete source code of the FDK AAC Codec and your
47*e5436536SAndroid Build Coastguard Worker modifications thereto to recipients of copies in binary form.
48*e5436536SAndroid Build Coastguard Worker 
49*e5436536SAndroid Build Coastguard Worker The name of Fraunhofer may not be used to endorse or promote products derived
50*e5436536SAndroid Build Coastguard Worker from this library without prior written permission.
51*e5436536SAndroid Build Coastguard Worker 
52*e5436536SAndroid Build Coastguard Worker You may not charge copyright license fees for anyone to use, copy or distribute
53*e5436536SAndroid Build Coastguard Worker the FDK AAC Codec software or your modifications thereto.
54*e5436536SAndroid Build Coastguard Worker 
55*e5436536SAndroid Build Coastguard Worker Your modified versions of the FDK AAC Codec must carry prominent notices stating
56*e5436536SAndroid Build Coastguard Worker that you changed the software and the date of any change. For modified versions
57*e5436536SAndroid Build Coastguard Worker of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
58*e5436536SAndroid Build Coastguard Worker must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
59*e5436536SAndroid Build Coastguard Worker AAC Codec Library for Android."
60*e5436536SAndroid Build Coastguard Worker 
61*e5436536SAndroid Build Coastguard Worker 3.    NO PATENT LICENSE
62*e5436536SAndroid Build Coastguard Worker 
63*e5436536SAndroid Build Coastguard Worker NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
64*e5436536SAndroid Build Coastguard Worker limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
65*e5436536SAndroid Build Coastguard Worker Fraunhofer provides no warranty of patent non-infringement with respect to this
66*e5436536SAndroid Build Coastguard Worker software.
67*e5436536SAndroid Build Coastguard Worker 
68*e5436536SAndroid Build Coastguard Worker You may use this FDK AAC Codec software or modifications thereto only for
69*e5436536SAndroid Build Coastguard Worker purposes that are authorized by appropriate patent licenses.
70*e5436536SAndroid Build Coastguard Worker 
71*e5436536SAndroid Build Coastguard Worker 4.    DISCLAIMER
72*e5436536SAndroid Build Coastguard Worker 
73*e5436536SAndroid Build Coastguard Worker This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
74*e5436536SAndroid Build Coastguard Worker holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
75*e5436536SAndroid Build Coastguard Worker including but not limited to the implied warranties of merchantability and
76*e5436536SAndroid Build Coastguard Worker fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
77*e5436536SAndroid Build Coastguard Worker CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
78*e5436536SAndroid Build Coastguard Worker or consequential damages, including but not limited to procurement of substitute
79*e5436536SAndroid Build Coastguard Worker goods or services; loss of use, data, or profits, or business interruption,
80*e5436536SAndroid Build Coastguard Worker however caused and on any theory of liability, whether in contract, strict
81*e5436536SAndroid Build Coastguard Worker liability, or tort (including negligence), arising in any way out of the use of
82*e5436536SAndroid Build Coastguard Worker this software, even if advised of the possibility of such damage.
83*e5436536SAndroid Build Coastguard Worker 
84*e5436536SAndroid Build Coastguard Worker 5.    CONTACT INFORMATION
85*e5436536SAndroid Build Coastguard Worker 
86*e5436536SAndroid Build Coastguard Worker Fraunhofer Institute for Integrated Circuits IIS
87*e5436536SAndroid Build Coastguard Worker Attention: Audio and Multimedia Departments - FDK AAC LL
88*e5436536SAndroid Build Coastguard Worker Am Wolfsmantel 33
89*e5436536SAndroid Build Coastguard Worker 91058 Erlangen, Germany
90*e5436536SAndroid Build Coastguard Worker 
91*e5436536SAndroid Build Coastguard Worker www.iis.fraunhofer.de/amm
92*e5436536SAndroid Build Coastguard Worker [email protected]
93*e5436536SAndroid Build Coastguard Worker ----------------------------------------------------------------------------- */
94*e5436536SAndroid Build Coastguard Worker 
95*e5436536SAndroid Build Coastguard Worker /**************************** AAC encoder library ******************************
96*e5436536SAndroid Build Coastguard Worker 
97*e5436536SAndroid Build Coastguard Worker    Author(s):   M. Werner
98*e5436536SAndroid Build Coastguard Worker 
99*e5436536SAndroid Build Coastguard Worker    Description: Quantizing & coding
100*e5436536SAndroid Build Coastguard Worker 
101*e5436536SAndroid Build Coastguard Worker *******************************************************************************/
102*e5436536SAndroid Build Coastguard Worker 
103*e5436536SAndroid Build Coastguard Worker #include "qc_main.h"
104*e5436536SAndroid Build Coastguard Worker #include "quantize.h"
105*e5436536SAndroid Build Coastguard Worker #include "interface.h"
106*e5436536SAndroid Build Coastguard Worker #include "adj_thr.h"
107*e5436536SAndroid Build Coastguard Worker #include "sf_estim.h"
108*e5436536SAndroid Build Coastguard Worker #include "bit_cnt.h"
109*e5436536SAndroid Build Coastguard Worker #include "dyn_bits.h"
110*e5436536SAndroid Build Coastguard Worker #include "channel_map.h"
111*e5436536SAndroid Build Coastguard Worker #include "aacEnc_ram.h"
112*e5436536SAndroid Build Coastguard Worker 
113*e5436536SAndroid Build Coastguard Worker #include "genericStds.h"
114*e5436536SAndroid Build Coastguard Worker 
115*e5436536SAndroid Build Coastguard Worker #define AACENC_DZQ_BR_THR 32000 /* Dead zone quantizer bitrate threshold */
116*e5436536SAndroid Build Coastguard Worker 
117*e5436536SAndroid Build Coastguard Worker typedef struct {
118*e5436536SAndroid Build Coastguard Worker   QCDATA_BR_MODE bitrateMode;
119*e5436536SAndroid Build Coastguard Worker   LONG vbrQualFactor;
120*e5436536SAndroid Build Coastguard Worker } TAB_VBR_QUAL_FACTOR;
121*e5436536SAndroid Build Coastguard Worker 
122*e5436536SAndroid Build Coastguard Worker static const TAB_VBR_QUAL_FACTOR tableVbrQualFactor[] = {
123*e5436536SAndroid Build Coastguard Worker     {QCDATA_BR_MODE_VBR_1,
124*e5436536SAndroid Build Coastguard Worker      FL2FXCONST_DBL(0.150f)}, /* Approx.  32 kbps mono   AAC-LC + SBR + PS */
125*e5436536SAndroid Build Coastguard Worker     {QCDATA_BR_MODE_VBR_2,
126*e5436536SAndroid Build Coastguard Worker      FL2FXCONST_DBL(0.162f)}, /* Approx.  64 kbps stereo AAC-LC + SBR      */
127*e5436536SAndroid Build Coastguard Worker     {QCDATA_BR_MODE_VBR_3,
128*e5436536SAndroid Build Coastguard Worker      FL2FXCONST_DBL(0.176f)}, /* Approx.  96 kbps stereo AAC-LC            */
129*e5436536SAndroid Build Coastguard Worker     {QCDATA_BR_MODE_VBR_4,
130*e5436536SAndroid Build Coastguard Worker      FL2FXCONST_DBL(0.120f)}, /* Approx. 128 kbps stereo AAC-LC            */
131*e5436536SAndroid Build Coastguard Worker     {QCDATA_BR_MODE_VBR_5,
132*e5436536SAndroid Build Coastguard Worker      FL2FXCONST_DBL(0.070f)} /* Approx. 192 kbps stereo AAC-LC            */
133*e5436536SAndroid Build Coastguard Worker };
134*e5436536SAndroid Build Coastguard Worker 
isConstantBitrateMode(const QCDATA_BR_MODE bitrateMode)135*e5436536SAndroid Build Coastguard Worker static INT isConstantBitrateMode(const QCDATA_BR_MODE bitrateMode) {
136*e5436536SAndroid Build Coastguard Worker   return (((bitrateMode == QCDATA_BR_MODE_CBR) ||
137*e5436536SAndroid Build Coastguard Worker            (bitrateMode == QCDATA_BR_MODE_SFR) ||
138*e5436536SAndroid Build Coastguard Worker            (bitrateMode == QCDATA_BR_MODE_FF))
139*e5436536SAndroid Build Coastguard Worker               ? 1
140*e5436536SAndroid Build Coastguard Worker               : 0);
141*e5436536SAndroid Build Coastguard Worker }
142*e5436536SAndroid Build Coastguard Worker 
143*e5436536SAndroid Build Coastguard Worker typedef enum {
144*e5436536SAndroid Build Coastguard Worker   FRAME_LEN_BYTES_MODULO = 1,
145*e5436536SAndroid Build Coastguard Worker   FRAME_LEN_BYTES_INT = 2
146*e5436536SAndroid Build Coastguard Worker } FRAME_LEN_RESULT_MODE;
147*e5436536SAndroid Build Coastguard Worker 
148*e5436536SAndroid Build Coastguard Worker /* forward declarations */
149*e5436536SAndroid Build Coastguard Worker 
150*e5436536SAndroid Build Coastguard Worker static INT FDKaacEnc_calcMaxValueInSfb(INT sfbCnt, INT maxSfbPerGroup,
151*e5436536SAndroid Build Coastguard Worker                                        INT sfbPerGroup, INT* RESTRICT sfbOffset,
152*e5436536SAndroid Build Coastguard Worker                                        SHORT* RESTRICT quantSpectrum,
153*e5436536SAndroid Build Coastguard Worker                                        UINT* RESTRICT maxValue);
154*e5436536SAndroid Build Coastguard Worker 
155*e5436536SAndroid Build Coastguard Worker static void FDKaacEnc_crashRecovery(INT nChannels,
156*e5436536SAndroid Build Coastguard Worker                                     PSY_OUT_ELEMENT* psyOutElement,
157*e5436536SAndroid Build Coastguard Worker                                     QC_OUT* qcOut, QC_OUT_ELEMENT* qcElement,
158*e5436536SAndroid Build Coastguard Worker                                     INT bitsToSave, AUDIO_OBJECT_TYPE aot,
159*e5436536SAndroid Build Coastguard Worker                                     UINT syntaxFlags, SCHAR epConfig);
160*e5436536SAndroid Build Coastguard Worker 
161*e5436536SAndroid Build Coastguard Worker static AAC_ENCODER_ERROR FDKaacEnc_reduceBitConsumption(
162*e5436536SAndroid Build Coastguard Worker     int* iterations, const int maxIterations, int gainAdjustment,
163*e5436536SAndroid Build Coastguard Worker     int* chConstraintsFulfilled, int* calculateQuant, int nChannels,
164*e5436536SAndroid Build Coastguard Worker     PSY_OUT_ELEMENT* psyOutElement, QC_OUT* qcOut, QC_OUT_ELEMENT* qcOutElement,
165*e5436536SAndroid Build Coastguard Worker     ELEMENT_BITS* elBits, AUDIO_OBJECT_TYPE aot, UINT syntaxFlags,
166*e5436536SAndroid Build Coastguard Worker     SCHAR epConfig);
167*e5436536SAndroid Build Coastguard Worker 
168*e5436536SAndroid Build Coastguard Worker void FDKaacEnc_QCClose(QC_STATE** phQCstate, QC_OUT** phQC);
169*e5436536SAndroid Build Coastguard Worker 
170*e5436536SAndroid Build Coastguard Worker /*****************************************************************************
171*e5436536SAndroid Build Coastguard Worker 
172*e5436536SAndroid Build Coastguard Worker     functionname: FDKaacEnc_calcFrameLen
173*e5436536SAndroid Build Coastguard Worker     description:
174*e5436536SAndroid Build Coastguard Worker     returns:
175*e5436536SAndroid Build Coastguard Worker     input:
176*e5436536SAndroid Build Coastguard Worker     output:
177*e5436536SAndroid Build Coastguard Worker 
178*e5436536SAndroid Build Coastguard Worker *****************************************************************************/
FDKaacEnc_calcFrameLen(INT bitRate,INT sampleRate,INT granuleLength,FRAME_LEN_RESULT_MODE mode)179*e5436536SAndroid Build Coastguard Worker static INT FDKaacEnc_calcFrameLen(INT bitRate, INT sampleRate,
180*e5436536SAndroid Build Coastguard Worker                                   INT granuleLength,
181*e5436536SAndroid Build Coastguard Worker                                   FRAME_LEN_RESULT_MODE mode) {
182*e5436536SAndroid Build Coastguard Worker   INT result;
183*e5436536SAndroid Build Coastguard Worker 
184*e5436536SAndroid Build Coastguard Worker   result = ((granuleLength) >> 3) * (bitRate);
185*e5436536SAndroid Build Coastguard Worker 
186*e5436536SAndroid Build Coastguard Worker   switch (mode) {
187*e5436536SAndroid Build Coastguard Worker     case FRAME_LEN_BYTES_MODULO:
188*e5436536SAndroid Build Coastguard Worker       result %= sampleRate;
189*e5436536SAndroid Build Coastguard Worker       break;
190*e5436536SAndroid Build Coastguard Worker     case FRAME_LEN_BYTES_INT:
191*e5436536SAndroid Build Coastguard Worker       result /= sampleRate;
192*e5436536SAndroid Build Coastguard Worker       break;
193*e5436536SAndroid Build Coastguard Worker   }
194*e5436536SAndroid Build Coastguard Worker   return (result);
195*e5436536SAndroid Build Coastguard Worker }
196*e5436536SAndroid Build Coastguard Worker 
197*e5436536SAndroid Build Coastguard Worker /*****************************************************************************
198*e5436536SAndroid Build Coastguard Worker 
199*e5436536SAndroid Build Coastguard Worker     functionname:FDKaacEnc_framePadding
200*e5436536SAndroid Build Coastguard Worker     description: Calculates if padding is needed for actual frame
201*e5436536SAndroid Build Coastguard Worker     returns:
202*e5436536SAndroid Build Coastguard Worker     input:
203*e5436536SAndroid Build Coastguard Worker     output:
204*e5436536SAndroid Build Coastguard Worker 
205*e5436536SAndroid Build Coastguard Worker *****************************************************************************/
FDKaacEnc_framePadding(INT bitRate,INT sampleRate,INT granuleLength,INT * paddingRest)206*e5436536SAndroid Build Coastguard Worker static INT FDKaacEnc_framePadding(INT bitRate, INT sampleRate,
207*e5436536SAndroid Build Coastguard Worker                                   INT granuleLength, INT* paddingRest) {
208*e5436536SAndroid Build Coastguard Worker   INT paddingOn;
209*e5436536SAndroid Build Coastguard Worker   INT difference;
210*e5436536SAndroid Build Coastguard Worker 
211*e5436536SAndroid Build Coastguard Worker   paddingOn = 0;
212*e5436536SAndroid Build Coastguard Worker 
213*e5436536SAndroid Build Coastguard Worker   difference = FDKaacEnc_calcFrameLen(bitRate, sampleRate, granuleLength,
214*e5436536SAndroid Build Coastguard Worker                                       FRAME_LEN_BYTES_MODULO);
215*e5436536SAndroid Build Coastguard Worker   *paddingRest -= difference;
216*e5436536SAndroid Build Coastguard Worker 
217*e5436536SAndroid Build Coastguard Worker   if (*paddingRest <= 0) {
218*e5436536SAndroid Build Coastguard Worker     paddingOn = 1;
219*e5436536SAndroid Build Coastguard Worker     *paddingRest += sampleRate;
220*e5436536SAndroid Build Coastguard Worker   }
221*e5436536SAndroid Build Coastguard Worker 
222*e5436536SAndroid Build Coastguard Worker   return (paddingOn);
223*e5436536SAndroid Build Coastguard Worker }
224*e5436536SAndroid Build Coastguard Worker 
225*e5436536SAndroid Build Coastguard Worker /*********************************************************************************
226*e5436536SAndroid Build Coastguard Worker 
227*e5436536SAndroid Build Coastguard Worker          functionname: FDKaacEnc_QCOutNew
228*e5436536SAndroid Build Coastguard Worker          description:
229*e5436536SAndroid Build Coastguard Worker          return:
230*e5436536SAndroid Build Coastguard Worker 
231*e5436536SAndroid Build Coastguard Worker **********************************************************************************/
FDKaacEnc_QCOutNew(QC_OUT ** phQC,const INT nElements,const INT nChannels,const INT nSubFrames,UCHAR * dynamic_RAM)232*e5436536SAndroid Build Coastguard Worker AAC_ENCODER_ERROR FDKaacEnc_QCOutNew(QC_OUT** phQC, const INT nElements,
233*e5436536SAndroid Build Coastguard Worker                                      const INT nChannels, const INT nSubFrames,
234*e5436536SAndroid Build Coastguard Worker                                      UCHAR* dynamic_RAM) {
235*e5436536SAndroid Build Coastguard Worker   AAC_ENCODER_ERROR ErrorStatus;
236*e5436536SAndroid Build Coastguard Worker   int n, i;
237*e5436536SAndroid Build Coastguard Worker   int elInc = 0, chInc = 0;
238*e5436536SAndroid Build Coastguard Worker 
239*e5436536SAndroid Build Coastguard Worker   for (n = 0; n < nSubFrames; n++) {
240*e5436536SAndroid Build Coastguard Worker     phQC[n] = GetRam_aacEnc_QCout(n);
241*e5436536SAndroid Build Coastguard Worker     if (phQC[n] == NULL) {
242*e5436536SAndroid Build Coastguard Worker       ErrorStatus = AAC_ENC_NO_MEMORY;
243*e5436536SAndroid Build Coastguard Worker       goto QCOutNew_bail;
244*e5436536SAndroid Build Coastguard Worker     }
245*e5436536SAndroid Build Coastguard Worker 
246*e5436536SAndroid Build Coastguard Worker     for (i = 0; i < nChannels; i++) {
247*e5436536SAndroid Build Coastguard Worker       phQC[n]->pQcOutChannels[i] = GetRam_aacEnc_QCchannel(chInc, dynamic_RAM);
248*e5436536SAndroid Build Coastguard Worker       if (phQC[n]->pQcOutChannels[i] == NULL) {
249*e5436536SAndroid Build Coastguard Worker         ErrorStatus = AAC_ENC_NO_MEMORY;
250*e5436536SAndroid Build Coastguard Worker         goto QCOutNew_bail;
251*e5436536SAndroid Build Coastguard Worker       }
252*e5436536SAndroid Build Coastguard Worker 
253*e5436536SAndroid Build Coastguard Worker       chInc++;
254*e5436536SAndroid Build Coastguard Worker     } /* nChannels */
255*e5436536SAndroid Build Coastguard Worker 
256*e5436536SAndroid Build Coastguard Worker     for (i = 0; i < nElements; i++) {
257*e5436536SAndroid Build Coastguard Worker       phQC[n]->qcElement[i] = GetRam_aacEnc_QCelement(elInc);
258*e5436536SAndroid Build Coastguard Worker       if (phQC[n]->qcElement[i] == NULL) {
259*e5436536SAndroid Build Coastguard Worker         ErrorStatus = AAC_ENC_NO_MEMORY;
260*e5436536SAndroid Build Coastguard Worker         goto QCOutNew_bail;
261*e5436536SAndroid Build Coastguard Worker       }
262*e5436536SAndroid Build Coastguard Worker       elInc++;
263*e5436536SAndroid Build Coastguard Worker 
264*e5436536SAndroid Build Coastguard Worker       /* initialize pointer to dynamic buffer which are used in adjust
265*e5436536SAndroid Build Coastguard Worker        * thresholds */
266*e5436536SAndroid Build Coastguard Worker       phQC[n]->qcElement[i]->dynMem_Ah_Flag = dynamic_RAM + (P_BUF_1);
267*e5436536SAndroid Build Coastguard Worker       phQC[n]->qcElement[i]->dynMem_Thr_Exp =
268*e5436536SAndroid Build Coastguard Worker           dynamic_RAM + (P_BUF_1) + ADJ_THR_AH_FLAG_SIZE;
269*e5436536SAndroid Build Coastguard Worker       phQC[n]->qcElement[i]->dynMem_SfbNActiveLinesLdData =
270*e5436536SAndroid Build Coastguard Worker           dynamic_RAM + (P_BUF_1) + ADJ_THR_AH_FLAG_SIZE + ADJ_THR_THR_EXP_SIZE;
271*e5436536SAndroid Build Coastguard Worker 
272*e5436536SAndroid Build Coastguard Worker     } /* nElements */
273*e5436536SAndroid Build Coastguard Worker 
274*e5436536SAndroid Build Coastguard Worker   } /* nSubFrames */
275*e5436536SAndroid Build Coastguard Worker 
276*e5436536SAndroid Build Coastguard Worker   return AAC_ENC_OK;
277*e5436536SAndroid Build Coastguard Worker 
278*e5436536SAndroid Build Coastguard Worker QCOutNew_bail:
279*e5436536SAndroid Build Coastguard Worker   return ErrorStatus;
280*e5436536SAndroid Build Coastguard Worker }
281*e5436536SAndroid Build Coastguard Worker 
282*e5436536SAndroid Build Coastguard Worker /*********************************************************************************
283*e5436536SAndroid Build Coastguard Worker 
284*e5436536SAndroid Build Coastguard Worker          functionname: FDKaacEnc_QCOutInit
285*e5436536SAndroid Build Coastguard Worker          description:
286*e5436536SAndroid Build Coastguard Worker          return:
287*e5436536SAndroid Build Coastguard Worker 
288*e5436536SAndroid Build Coastguard Worker **********************************************************************************/
FDKaacEnc_QCOutInit(QC_OUT * phQC[(1)],const INT nSubFrames,const CHANNEL_MAPPING * cm)289*e5436536SAndroid Build Coastguard Worker AAC_ENCODER_ERROR FDKaacEnc_QCOutInit(QC_OUT* phQC[(1)], const INT nSubFrames,
290*e5436536SAndroid Build Coastguard Worker                                       const CHANNEL_MAPPING* cm) {
291*e5436536SAndroid Build Coastguard Worker   INT n, i, ch;
292*e5436536SAndroid Build Coastguard Worker 
293*e5436536SAndroid Build Coastguard Worker   for (n = 0; n < nSubFrames; n++) {
294*e5436536SAndroid Build Coastguard Worker     INT chInc = 0;
295*e5436536SAndroid Build Coastguard Worker     for (i = 0; i < cm->nElements; i++) {
296*e5436536SAndroid Build Coastguard Worker       for (ch = 0; ch < cm->elInfo[i].nChannelsInEl; ch++) {
297*e5436536SAndroid Build Coastguard Worker         phQC[n]->qcElement[i]->qcOutChannel[ch] =
298*e5436536SAndroid Build Coastguard Worker             phQC[n]->pQcOutChannels[chInc];
299*e5436536SAndroid Build Coastguard Worker         chInc++;
300*e5436536SAndroid Build Coastguard Worker       } /* chInEl */
301*e5436536SAndroid Build Coastguard Worker     }   /* nElements */
302*e5436536SAndroid Build Coastguard Worker   }     /* nSubFrames */
303*e5436536SAndroid Build Coastguard Worker 
304*e5436536SAndroid Build Coastguard Worker   return AAC_ENC_OK;
305*e5436536SAndroid Build Coastguard Worker }
306*e5436536SAndroid Build Coastguard Worker 
307*e5436536SAndroid Build Coastguard Worker /*********************************************************************************
308*e5436536SAndroid Build Coastguard Worker 
309*e5436536SAndroid Build Coastguard Worker          functionname: FDKaacEnc_QCNew
310*e5436536SAndroid Build Coastguard Worker          description:
311*e5436536SAndroid Build Coastguard Worker          return:
312*e5436536SAndroid Build Coastguard Worker 
313*e5436536SAndroid Build Coastguard Worker **********************************************************************************/
FDKaacEnc_QCNew(QC_STATE ** phQC,INT nElements,UCHAR * dynamic_RAM)314*e5436536SAndroid Build Coastguard Worker AAC_ENCODER_ERROR FDKaacEnc_QCNew(QC_STATE** phQC, INT nElements,
315*e5436536SAndroid Build Coastguard Worker                                   UCHAR* dynamic_RAM) {
316*e5436536SAndroid Build Coastguard Worker   AAC_ENCODER_ERROR ErrorStatus;
317*e5436536SAndroid Build Coastguard Worker   int i;
318*e5436536SAndroid Build Coastguard Worker 
319*e5436536SAndroid Build Coastguard Worker   QC_STATE* hQC = GetRam_aacEnc_QCstate();
320*e5436536SAndroid Build Coastguard Worker   *phQC = hQC;
321*e5436536SAndroid Build Coastguard Worker   if (hQC == NULL) {
322*e5436536SAndroid Build Coastguard Worker     ErrorStatus = AAC_ENC_NO_MEMORY;
323*e5436536SAndroid Build Coastguard Worker     goto QCNew_bail;
324*e5436536SAndroid Build Coastguard Worker   }
325*e5436536SAndroid Build Coastguard Worker 
326*e5436536SAndroid Build Coastguard Worker   if (FDKaacEnc_AdjThrNew(&hQC->hAdjThr, nElements)) {
327*e5436536SAndroid Build Coastguard Worker     ErrorStatus = AAC_ENC_NO_MEMORY;
328*e5436536SAndroid Build Coastguard Worker     goto QCNew_bail;
329*e5436536SAndroid Build Coastguard Worker   }
330*e5436536SAndroid Build Coastguard Worker 
331*e5436536SAndroid Build Coastguard Worker   if (FDKaacEnc_BCNew(&(hQC->hBitCounter), dynamic_RAM)) {
332*e5436536SAndroid Build Coastguard Worker     ErrorStatus = AAC_ENC_NO_MEMORY;
333*e5436536SAndroid Build Coastguard Worker     goto QCNew_bail;
334*e5436536SAndroid Build Coastguard Worker   }
335*e5436536SAndroid Build Coastguard Worker 
336*e5436536SAndroid Build Coastguard Worker   for (i = 0; i < nElements; i++) {
337*e5436536SAndroid Build Coastguard Worker     hQC->elementBits[i] = GetRam_aacEnc_ElementBits(i);
338*e5436536SAndroid Build Coastguard Worker     if (hQC->elementBits[i] == NULL) {
339*e5436536SAndroid Build Coastguard Worker       ErrorStatus = AAC_ENC_NO_MEMORY;
340*e5436536SAndroid Build Coastguard Worker       goto QCNew_bail;
341*e5436536SAndroid Build Coastguard Worker     }
342*e5436536SAndroid Build Coastguard Worker   }
343*e5436536SAndroid Build Coastguard Worker 
344*e5436536SAndroid Build Coastguard Worker   return AAC_ENC_OK;
345*e5436536SAndroid Build Coastguard Worker 
346*e5436536SAndroid Build Coastguard Worker QCNew_bail:
347*e5436536SAndroid Build Coastguard Worker   FDKaacEnc_QCClose(phQC, NULL);
348*e5436536SAndroid Build Coastguard Worker   return ErrorStatus;
349*e5436536SAndroid Build Coastguard Worker }
350*e5436536SAndroid Build Coastguard Worker 
351*e5436536SAndroid Build Coastguard Worker /*********************************************************************************
352*e5436536SAndroid Build Coastguard Worker 
353*e5436536SAndroid Build Coastguard Worker          functionname: FDKaacEnc_QCInit
354*e5436536SAndroid Build Coastguard Worker          description:
355*e5436536SAndroid Build Coastguard Worker          return:
356*e5436536SAndroid Build Coastguard Worker 
357*e5436536SAndroid Build Coastguard Worker **********************************************************************************/
FDKaacEnc_QCInit(QC_STATE * hQC,struct QC_INIT * init,const ULONG initFlags)358*e5436536SAndroid Build Coastguard Worker AAC_ENCODER_ERROR FDKaacEnc_QCInit(QC_STATE* hQC, struct QC_INIT* init,
359*e5436536SAndroid Build Coastguard Worker                                    const ULONG initFlags) {
360*e5436536SAndroid Build Coastguard Worker   AAC_ENCODER_ERROR err = AAC_ENC_OK;
361*e5436536SAndroid Build Coastguard Worker 
362*e5436536SAndroid Build Coastguard Worker   int i;
363*e5436536SAndroid Build Coastguard Worker   hQC->maxBitsPerFrame = init->maxBits;
364*e5436536SAndroid Build Coastguard Worker   hQC->minBitsPerFrame = init->minBits;
365*e5436536SAndroid Build Coastguard Worker   hQC->nElements = init->channelMapping->nElements;
366*e5436536SAndroid Build Coastguard Worker   if ((initFlags != 0) || ((init->bitrateMode != QCDATA_BR_MODE_FF) &&
367*e5436536SAndroid Build Coastguard Worker                            (hQC->bitResTotMax != init->bitRes))) {
368*e5436536SAndroid Build Coastguard Worker     hQC->bitResTot = init->bitRes;
369*e5436536SAndroid Build Coastguard Worker   }
370*e5436536SAndroid Build Coastguard Worker   hQC->bitResTotMax = init->bitRes;
371*e5436536SAndroid Build Coastguard Worker   hQC->maxBitFac = init->maxBitFac;
372*e5436536SAndroid Build Coastguard Worker   hQC->bitrateMode = init->bitrateMode;
373*e5436536SAndroid Build Coastguard Worker   hQC->invQuant = init->invQuant;
374*e5436536SAndroid Build Coastguard Worker   hQC->maxIterations = init->maxIterations;
375*e5436536SAndroid Build Coastguard Worker 
376*e5436536SAndroid Build Coastguard Worker   /* 0: full bitreservoir, 1: reduced bitreservoir, 2: disabled bitreservoir */
377*e5436536SAndroid Build Coastguard Worker   hQC->bitResMode = init->bitResMode;
378*e5436536SAndroid Build Coastguard Worker 
379*e5436536SAndroid Build Coastguard Worker   hQC->padding.paddingRest = init->padding.paddingRest;
380*e5436536SAndroid Build Coastguard Worker 
381*e5436536SAndroid Build Coastguard Worker   hQC->globHdrBits = init->staticBits; /* Bit overhead due to transport */
382*e5436536SAndroid Build Coastguard Worker 
383*e5436536SAndroid Build Coastguard Worker   err = FDKaacEnc_InitElementBits(
384*e5436536SAndroid Build Coastguard Worker       hQC, init->channelMapping, init->bitrate,
385*e5436536SAndroid Build Coastguard Worker       (init->averageBits / init->nSubFrames) - hQC->globHdrBits,
386*e5436536SAndroid Build Coastguard Worker       hQC->maxBitsPerFrame / init->channelMapping->nChannelsEff);
387*e5436536SAndroid Build Coastguard Worker   if (err != AAC_ENC_OK) goto bail;
388*e5436536SAndroid Build Coastguard Worker 
389*e5436536SAndroid Build Coastguard Worker   hQC->vbrQualFactor = FL2FXCONST_DBL(0.f);
390*e5436536SAndroid Build Coastguard Worker   for (i = 0;
391*e5436536SAndroid Build Coastguard Worker        i < (int)(sizeof(tableVbrQualFactor) / sizeof(TAB_VBR_QUAL_FACTOR));
392*e5436536SAndroid Build Coastguard Worker        i++) {
393*e5436536SAndroid Build Coastguard Worker     if (hQC->bitrateMode == tableVbrQualFactor[i].bitrateMode) {
394*e5436536SAndroid Build Coastguard Worker       hQC->vbrQualFactor = (FIXP_DBL)tableVbrQualFactor[i].vbrQualFactor;
395*e5436536SAndroid Build Coastguard Worker       break;
396*e5436536SAndroid Build Coastguard Worker     }
397*e5436536SAndroid Build Coastguard Worker   }
398*e5436536SAndroid Build Coastguard Worker 
399*e5436536SAndroid Build Coastguard Worker   if (init->channelMapping->nChannelsEff == 1 &&
400*e5436536SAndroid Build Coastguard Worker       (init->bitrate / init->channelMapping->nChannelsEff) <
401*e5436536SAndroid Build Coastguard Worker           AACENC_DZQ_BR_THR &&
402*e5436536SAndroid Build Coastguard Worker       init->isLowDelay !=
403*e5436536SAndroid Build Coastguard Worker           0) /* watch out here: init->bitrate is the bitrate "minus" the
404*e5436536SAndroid Build Coastguard Worker                 standard SBR bitrate (=2500kbps) --> for the FDK the OFFSTE
405*e5436536SAndroid Build Coastguard Worker                 tuning should start somewhere below 32000kbps-2500kbps ... so
406*e5436536SAndroid Build Coastguard Worker                 everything is fine here */
407*e5436536SAndroid Build Coastguard Worker   {
408*e5436536SAndroid Build Coastguard Worker     hQC->dZoneQuantEnable = 1;
409*e5436536SAndroid Build Coastguard Worker   } else {
410*e5436536SAndroid Build Coastguard Worker     hQC->dZoneQuantEnable = 0;
411*e5436536SAndroid Build Coastguard Worker   }
412*e5436536SAndroid Build Coastguard Worker 
413*e5436536SAndroid Build Coastguard Worker   FDKaacEnc_AdjThrInit(
414*e5436536SAndroid Build Coastguard Worker       hQC->hAdjThr, init->meanPe, hQC->invQuant, init->channelMapping,
415*e5436536SAndroid Build Coastguard Worker       init->sampleRate, /* output sample rate */
416*e5436536SAndroid Build Coastguard Worker       init->bitrate,    /* total bitrate */
417*e5436536SAndroid Build Coastguard Worker       init->isLowDelay, /* if set, calc bits2PE factor
418*e5436536SAndroid Build Coastguard Worker                            depending on samplerate */
419*e5436536SAndroid Build Coastguard Worker       init->bitResMode  /* for a small bitreservoir, the pe
420*e5436536SAndroid Build Coastguard Worker                            correction is calc'd differently */
421*e5436536SAndroid Build Coastguard Worker       ,
422*e5436536SAndroid Build Coastguard Worker       hQC->dZoneQuantEnable, init->bitDistributionMode, hQC->vbrQualFactor);
423*e5436536SAndroid Build Coastguard Worker 
424*e5436536SAndroid Build Coastguard Worker bail:
425*e5436536SAndroid Build Coastguard Worker   return err;
426*e5436536SAndroid Build Coastguard Worker }
427*e5436536SAndroid Build Coastguard Worker 
428*e5436536SAndroid Build Coastguard Worker /*********************************************************************************
429*e5436536SAndroid Build Coastguard Worker 
430*e5436536SAndroid Build Coastguard Worker          functionname: FDKaacEnc_QCMainPrepare
431*e5436536SAndroid Build Coastguard Worker          description:
432*e5436536SAndroid Build Coastguard Worker          return:
433*e5436536SAndroid Build Coastguard Worker 
434*e5436536SAndroid Build Coastguard Worker **********************************************************************************/
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)435*e5436536SAndroid Build Coastguard Worker AAC_ENCODER_ERROR FDKaacEnc_QCMainPrepare(
436*e5436536SAndroid Build Coastguard Worker     ELEMENT_INFO* elInfo, ATS_ELEMENT* RESTRICT adjThrStateElement,
437*e5436536SAndroid Build Coastguard Worker     PSY_OUT_ELEMENT* RESTRICT psyOutElement,
438*e5436536SAndroid Build Coastguard Worker     QC_OUT_ELEMENT* RESTRICT qcOutElement, AUDIO_OBJECT_TYPE aot,
439*e5436536SAndroid Build Coastguard Worker     UINT syntaxFlags, SCHAR epConfig) {
440*e5436536SAndroid Build Coastguard Worker   AAC_ENCODER_ERROR ErrorStatus = AAC_ENC_OK;
441*e5436536SAndroid Build Coastguard Worker   INT nChannels = elInfo->nChannelsInEl;
442*e5436536SAndroid Build Coastguard Worker 
443*e5436536SAndroid Build Coastguard Worker   PSY_OUT_CHANNEL** RESTRICT psyOutChannel =
444*e5436536SAndroid Build Coastguard Worker       psyOutElement->psyOutChannel; /* may be modified in-place */
445*e5436536SAndroid Build Coastguard Worker 
446*e5436536SAndroid Build Coastguard Worker   FDKaacEnc_CalcFormFactor(qcOutElement->qcOutChannel, psyOutChannel,
447*e5436536SAndroid Build Coastguard Worker                            nChannels);
448*e5436536SAndroid Build Coastguard Worker 
449*e5436536SAndroid Build Coastguard Worker   /* prepare and calculate PE without reduction */
450*e5436536SAndroid Build Coastguard Worker   FDKaacEnc_peCalculation(&qcOutElement->peData, psyOutChannel,
451*e5436536SAndroid Build Coastguard Worker                           qcOutElement->qcOutChannel, &psyOutElement->toolsInfo,
452*e5436536SAndroid Build Coastguard Worker                           adjThrStateElement, nChannels);
453*e5436536SAndroid Build Coastguard Worker 
454*e5436536SAndroid Build Coastguard Worker   ErrorStatus = FDKaacEnc_ChannelElementWrite(
455*e5436536SAndroid Build Coastguard Worker       NULL, elInfo, NULL, psyOutElement, psyOutElement->psyOutChannel,
456*e5436536SAndroid Build Coastguard Worker       syntaxFlags, aot, epConfig, &qcOutElement->staticBitsUsed, 0);
457*e5436536SAndroid Build Coastguard Worker 
458*e5436536SAndroid Build Coastguard Worker   return ErrorStatus;
459*e5436536SAndroid Build Coastguard Worker }
460*e5436536SAndroid Build Coastguard Worker 
461*e5436536SAndroid Build Coastguard Worker /*********************************************************************************
462*e5436536SAndroid Build Coastguard Worker 
463*e5436536SAndroid Build Coastguard Worker          functionname: FDKaacEnc_AdjustBitrate
464*e5436536SAndroid Build Coastguard Worker          description:  adjusts framelength via padding on a frame to frame
465*e5436536SAndroid Build Coastguard Worker basis, to achieve a bitrate that demands a non byte aligned framelength return:
466*e5436536SAndroid Build Coastguard Worker errorcode
467*e5436536SAndroid Build Coastguard Worker 
468*e5436536SAndroid Build Coastguard Worker **********************************************************************************/
FDKaacEnc_AdjustBitrate(QC_STATE * RESTRICT hQC,CHANNEL_MAPPING * RESTRICT cm,INT * avgTotalBits,INT bitRate,INT sampleRate,INT granuleLength)469*e5436536SAndroid Build Coastguard Worker AAC_ENCODER_ERROR FDKaacEnc_AdjustBitrate(
470*e5436536SAndroid Build Coastguard Worker     QC_STATE* RESTRICT hQC, CHANNEL_MAPPING* RESTRICT cm, INT* avgTotalBits,
471*e5436536SAndroid Build Coastguard Worker     INT bitRate,       /* total bitrate */
472*e5436536SAndroid Build Coastguard Worker     INT sampleRate,    /* output sampling rate */
473*e5436536SAndroid Build Coastguard Worker     INT granuleLength) /* frame length */
474*e5436536SAndroid Build Coastguard Worker {
475*e5436536SAndroid Build Coastguard Worker   INT paddingOn;
476*e5436536SAndroid Build Coastguard Worker   INT frameLen;
477*e5436536SAndroid Build Coastguard Worker 
478*e5436536SAndroid Build Coastguard Worker   /* Do we need an extra padding byte? */
479*e5436536SAndroid Build Coastguard Worker   paddingOn = FDKaacEnc_framePadding(bitRate, sampleRate, granuleLength,
480*e5436536SAndroid Build Coastguard Worker                                      &hQC->padding.paddingRest);
481*e5436536SAndroid Build Coastguard Worker 
482*e5436536SAndroid Build Coastguard Worker   frameLen =
483*e5436536SAndroid Build Coastguard Worker       paddingOn + FDKaacEnc_calcFrameLen(bitRate, sampleRate, granuleLength,
484*e5436536SAndroid Build Coastguard Worker                                          FRAME_LEN_BYTES_INT);
485*e5436536SAndroid Build Coastguard Worker 
486*e5436536SAndroid Build Coastguard Worker   *avgTotalBits = frameLen << 3;
487*e5436536SAndroid Build Coastguard Worker 
488*e5436536SAndroid Build Coastguard Worker   return AAC_ENC_OK;
489*e5436536SAndroid Build Coastguard Worker }
490*e5436536SAndroid Build Coastguard Worker 
491*e5436536SAndroid Build Coastguard Worker #define isAudioElement(elType) \
492*e5436536SAndroid Build Coastguard Worker   ((elType == ID_SCE) || (elType == ID_CPE) || (elType == ID_LFE))
493*e5436536SAndroid Build Coastguard Worker 
494*e5436536SAndroid Build Coastguard Worker /*********************************************************************************
495*e5436536SAndroid Build Coastguard Worker 
496*e5436536SAndroid Build Coastguard Worker          functionname: FDKaacEnc_distributeElementDynBits
497*e5436536SAndroid Build Coastguard Worker          description:  distributes all bits over all elements. The relative bit
498*e5436536SAndroid Build Coastguard Worker                        distibution is described in the ELEMENT_INFO of the
499*e5436536SAndroid Build Coastguard Worker                        appropriate element. The bit distribution table is
500*e5436536SAndroid Build Coastguard Worker                        initialized in FDKaacEnc_InitChannelMapping().
501*e5436536SAndroid Build Coastguard Worker          return:       errorcode
502*e5436536SAndroid Build Coastguard Worker 
503*e5436536SAndroid Build Coastguard Worker **********************************************************************************/
FDKaacEnc_distributeElementDynBits(QC_STATE * hQC,QC_OUT_ELEMENT * qcElement[((8))],CHANNEL_MAPPING * cm,INT codeBits)504*e5436536SAndroid Build Coastguard Worker static AAC_ENCODER_ERROR FDKaacEnc_distributeElementDynBits(
505*e5436536SAndroid Build Coastguard Worker     QC_STATE* hQC, QC_OUT_ELEMENT* qcElement[((8))], CHANNEL_MAPPING* cm,
506*e5436536SAndroid Build Coastguard Worker     INT codeBits) {
507*e5436536SAndroid Build Coastguard Worker   INT i;             /* counter variable */
508*e5436536SAndroid Build Coastguard Worker   INT totalBits = 0; /* sum of bits over all elements */
509*e5436536SAndroid Build Coastguard Worker 
510*e5436536SAndroid Build Coastguard Worker   for (i = (cm->nElements - 1); i >= 0; i--) {
511*e5436536SAndroid Build Coastguard Worker     if (isAudioElement(cm->elInfo[i].elType)) {
512*e5436536SAndroid Build Coastguard Worker       qcElement[i]->grantedDynBits =
513*e5436536SAndroid Build Coastguard Worker           fMax(0, fMultI(hQC->elementBits[i]->relativeBitsEl, codeBits));
514*e5436536SAndroid Build Coastguard Worker       totalBits += qcElement[i]->grantedDynBits;
515*e5436536SAndroid Build Coastguard Worker     }
516*e5436536SAndroid Build Coastguard Worker   }
517*e5436536SAndroid Build Coastguard Worker 
518*e5436536SAndroid Build Coastguard Worker   /* Due to inaccuracies with the multiplication, codeBits may differ from
519*e5436536SAndroid Build Coastguard Worker      totalBits. For that case, the difference must be added/substracted again
520*e5436536SAndroid Build Coastguard Worker      to/from one element, i.e:
521*e5436536SAndroid Build Coastguard Worker      Negative differences are substracted from the element with the most bits.
522*e5436536SAndroid Build Coastguard Worker      Positive differences are added to the element with the least bits.
523*e5436536SAndroid Build Coastguard Worker   */
524*e5436536SAndroid Build Coastguard Worker   if (codeBits != totalBits) {
525*e5436536SAndroid Build Coastguard Worker     INT elMaxBits = cm->nElements - 1; /* element with the most bits */
526*e5436536SAndroid Build Coastguard Worker     INT elMinBits = cm->nElements - 1; /* element with the least bits */
527*e5436536SAndroid Build Coastguard Worker 
528*e5436536SAndroid Build Coastguard Worker     /* Search for biggest and smallest audio element */
529*e5436536SAndroid Build Coastguard Worker     for (i = (cm->nElements - 1); i >= 0; i--) {
530*e5436536SAndroid Build Coastguard Worker       if (isAudioElement(cm->elInfo[i].elType)) {
531*e5436536SAndroid Build Coastguard Worker         if (qcElement[i]->grantedDynBits >
532*e5436536SAndroid Build Coastguard Worker             qcElement[elMaxBits]->grantedDynBits) {
533*e5436536SAndroid Build Coastguard Worker           elMaxBits = i;
534*e5436536SAndroid Build Coastguard Worker         }
535*e5436536SAndroid Build Coastguard Worker         if (qcElement[i]->grantedDynBits <
536*e5436536SAndroid Build Coastguard Worker             qcElement[elMinBits]->grantedDynBits) {
537*e5436536SAndroid Build Coastguard Worker           elMinBits = i;
538*e5436536SAndroid Build Coastguard Worker         }
539*e5436536SAndroid Build Coastguard Worker       }
540*e5436536SAndroid Build Coastguard Worker     }
541*e5436536SAndroid Build Coastguard Worker     /* Compensate for bit distibution difference */
542*e5436536SAndroid Build Coastguard Worker     if (codeBits - totalBits > 0) {
543*e5436536SAndroid Build Coastguard Worker       qcElement[elMinBits]->grantedDynBits += codeBits - totalBits;
544*e5436536SAndroid Build Coastguard Worker     } else {
545*e5436536SAndroid Build Coastguard Worker       qcElement[elMaxBits]->grantedDynBits += codeBits - totalBits;
546*e5436536SAndroid Build Coastguard Worker     }
547*e5436536SAndroid Build Coastguard Worker   }
548*e5436536SAndroid Build Coastguard Worker 
549*e5436536SAndroid Build Coastguard Worker   return AAC_ENC_OK;
550*e5436536SAndroid Build Coastguard Worker }
551*e5436536SAndroid Build Coastguard Worker 
552*e5436536SAndroid Build Coastguard Worker /**
553*e5436536SAndroid Build Coastguard Worker  * \brief  Verify whether minBitsPerFrame criterion can be satisfied.
554*e5436536SAndroid Build Coastguard Worker  *
555*e5436536SAndroid Build Coastguard Worker  * This function evaluates the bit consumption only if minBitsPerFrame parameter
556*e5436536SAndroid Build Coastguard Worker  * is not 0. In hyperframing mode the difference between grantedDynBits and
557*e5436536SAndroid Build Coastguard Worker  * usedDynBits of all sub frames results the number of fillbits to be written.
558*e5436536SAndroid Build Coastguard Worker  * This bits can be distrubitued in superframe to reach minBitsPerFrame bit
559*e5436536SAndroid Build Coastguard Worker  * consumption in single AU's. The return value denotes if enough desired fill
560*e5436536SAndroid Build Coastguard Worker  * bits are available to achieve minBitsPerFrame in all frames. This check can
561*e5436536SAndroid Build Coastguard Worker  * only be used within superframes.
562*e5436536SAndroid Build Coastguard Worker  *
563*e5436536SAndroid Build Coastguard Worker  * \param qcOut            Pointer to coding data struct.
564*e5436536SAndroid Build Coastguard Worker  * \param minBitsPerFrame  Minimal number of bits to be consumed in each frame.
565*e5436536SAndroid Build Coastguard Worker  * \param nSubFrames       Number of frames in superframe
566*e5436536SAndroid Build Coastguard Worker  *
567*e5436536SAndroid Build Coastguard Worker  * \return
568*e5436536SAndroid Build Coastguard Worker  *          - 1: all fine
569*e5436536SAndroid Build Coastguard Worker  *          - 0: criterion not fulfilled
570*e5436536SAndroid Build Coastguard Worker  */
checkMinFrameBitsDemand(QC_OUT ** qcOut,const INT minBitsPerFrame,const INT nSubFrames)571*e5436536SAndroid Build Coastguard Worker static int checkMinFrameBitsDemand(QC_OUT** qcOut, const INT minBitsPerFrame,
572*e5436536SAndroid Build Coastguard Worker                                    const INT nSubFrames) {
573*e5436536SAndroid Build Coastguard Worker   int result = 1; /* all fine*/
574*e5436536SAndroid Build Coastguard Worker   return result;
575*e5436536SAndroid Build Coastguard Worker }
576*e5436536SAndroid Build Coastguard Worker 
577*e5436536SAndroid Build Coastguard Worker ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
578*e5436536SAndroid Build Coastguard Worker 
579*e5436536SAndroid Build Coastguard Worker ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
580*e5436536SAndroid Build Coastguard Worker /*********************************************************************************
581*e5436536SAndroid Build Coastguard Worker 
582*e5436536SAndroid Build Coastguard Worker          functionname: FDKaacEnc_getMinimalStaticBitdemand
583*e5436536SAndroid Build Coastguard Worker          description:  calculate minmal size of static bits by reduction ,
584*e5436536SAndroid Build Coastguard Worker                        to zero spectrum and deactivating tns and MS
585*e5436536SAndroid Build Coastguard Worker          return:       number of static bits
586*e5436536SAndroid Build Coastguard Worker 
587*e5436536SAndroid Build Coastguard Worker **********************************************************************************/
FDKaacEnc_getMinimalStaticBitdemand(CHANNEL_MAPPING * cm,PSY_OUT ** psyOut)588*e5436536SAndroid Build Coastguard Worker static int FDKaacEnc_getMinimalStaticBitdemand(CHANNEL_MAPPING* cm,
589*e5436536SAndroid Build Coastguard Worker                                                PSY_OUT** psyOut) {
590*e5436536SAndroid Build Coastguard Worker   AUDIO_OBJECT_TYPE aot = AOT_AAC_LC;
591*e5436536SAndroid Build Coastguard Worker   UINT syntaxFlags = 0;
592*e5436536SAndroid Build Coastguard Worker   SCHAR epConfig = -1;
593*e5436536SAndroid Build Coastguard Worker   int i, bitcount = 0;
594*e5436536SAndroid Build Coastguard Worker 
595*e5436536SAndroid Build Coastguard Worker   for (i = 0; i < cm->nElements; i++) {
596*e5436536SAndroid Build Coastguard Worker     ELEMENT_INFO elInfo = cm->elInfo[i];
597*e5436536SAndroid Build Coastguard Worker 
598*e5436536SAndroid Build Coastguard Worker     if ((elInfo.elType == ID_SCE) || (elInfo.elType == ID_CPE) ||
599*e5436536SAndroid Build Coastguard Worker         (elInfo.elType == ID_LFE)) {
600*e5436536SAndroid Build Coastguard Worker       INT minElBits = 0;
601*e5436536SAndroid Build Coastguard Worker 
602*e5436536SAndroid Build Coastguard Worker       FDKaacEnc_ChannelElementWrite(NULL, &elInfo, NULL,
603*e5436536SAndroid Build Coastguard Worker                                     psyOut[0]->psyOutElement[i],
604*e5436536SAndroid Build Coastguard Worker                                     psyOut[0]->psyOutElement[i]->psyOutChannel,
605*e5436536SAndroid Build Coastguard Worker                                     syntaxFlags, aot, epConfig, &minElBits, 1);
606*e5436536SAndroid Build Coastguard Worker       bitcount += minElBits;
607*e5436536SAndroid Build Coastguard Worker     }
608*e5436536SAndroid Build Coastguard Worker   }
609*e5436536SAndroid Build Coastguard Worker 
610*e5436536SAndroid Build Coastguard Worker   return bitcount;
611*e5436536SAndroid Build Coastguard Worker }
612*e5436536SAndroid Build Coastguard Worker 
613*e5436536SAndroid Build Coastguard Worker ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
614*e5436536SAndroid Build Coastguard Worker 
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)615*e5436536SAndroid Build Coastguard Worker static AAC_ENCODER_ERROR FDKaacEnc_prepareBitDistribution(
616*e5436536SAndroid Build Coastguard Worker     QC_STATE* hQC, PSY_OUT** psyOut, QC_OUT** qcOut, CHANNEL_MAPPING* cm,
617*e5436536SAndroid Build Coastguard Worker     QC_OUT_ELEMENT* qcElement[(1)][((8))], INT avgTotalBits,
618*e5436536SAndroid Build Coastguard Worker     INT* totalAvailableBits, INT* avgTotalDynBits) {
619*e5436536SAndroid Build Coastguard Worker   int i;
620*e5436536SAndroid Build Coastguard Worker   /* get maximal allowed dynamic bits */
621*e5436536SAndroid Build Coastguard Worker   qcOut[0]->grantedDynBits =
622*e5436536SAndroid Build Coastguard Worker       (fixMin(hQC->maxBitsPerFrame, avgTotalBits) - hQC->globHdrBits) & ~7;
623*e5436536SAndroid Build Coastguard Worker   qcOut[0]->grantedDynBits -= (qcOut[0]->globalExtBits + qcOut[0]->staticBits +
624*e5436536SAndroid Build Coastguard Worker                                qcOut[0]->elementExtBits);
625*e5436536SAndroid Build Coastguard Worker   qcOut[0]->maxDynBits = ((hQC->maxBitsPerFrame) & ~7) -
626*e5436536SAndroid Build Coastguard Worker                          (qcOut[0]->globalExtBits + qcOut[0]->staticBits +
627*e5436536SAndroid Build Coastguard Worker                           qcOut[0]->elementExtBits);
628*e5436536SAndroid Build Coastguard Worker   /* assure that enough bits are available */
629*e5436536SAndroid Build Coastguard Worker   if ((qcOut[0]->grantedDynBits + hQC->bitResTot) < 0) {
630*e5436536SAndroid Build Coastguard Worker     /* crash recovery allows to reduce static bits to a minimum */
631*e5436536SAndroid Build Coastguard Worker     if ((qcOut[0]->grantedDynBits + hQC->bitResTot) <
632*e5436536SAndroid Build Coastguard Worker         (FDKaacEnc_getMinimalStaticBitdemand(cm, psyOut) -
633*e5436536SAndroid Build Coastguard Worker          qcOut[0]->staticBits))
634*e5436536SAndroid Build Coastguard Worker       return AAC_ENC_BITRES_TOO_LOW;
635*e5436536SAndroid Build Coastguard Worker   }
636*e5436536SAndroid Build Coastguard Worker 
637*e5436536SAndroid Build Coastguard Worker   /* distribute dynamic bits to each element */
638*e5436536SAndroid Build Coastguard Worker   FDKaacEnc_distributeElementDynBits(hQC, qcElement[0], cm,
639*e5436536SAndroid Build Coastguard Worker                                      qcOut[0]->grantedDynBits);
640*e5436536SAndroid Build Coastguard Worker 
641*e5436536SAndroid Build Coastguard Worker   *avgTotalDynBits = 0; /*frameDynBits;*/
642*e5436536SAndroid Build Coastguard Worker 
643*e5436536SAndroid Build Coastguard Worker   *totalAvailableBits = avgTotalBits;
644*e5436536SAndroid Build Coastguard Worker 
645*e5436536SAndroid Build Coastguard Worker   /* sum up corrected granted PE */
646*e5436536SAndroid Build Coastguard Worker   qcOut[0]->totalGrantedPeCorr = 0;
647*e5436536SAndroid Build Coastguard Worker 
648*e5436536SAndroid Build Coastguard Worker   for (i = 0; i < cm->nElements; i++) {
649*e5436536SAndroid Build Coastguard Worker     ELEMENT_INFO elInfo = cm->elInfo[i];
650*e5436536SAndroid Build Coastguard Worker     int nChannels = elInfo.nChannelsInEl;
651*e5436536SAndroid Build Coastguard Worker 
652*e5436536SAndroid Build Coastguard Worker     if ((elInfo.elType == ID_SCE) || (elInfo.elType == ID_CPE) ||
653*e5436536SAndroid Build Coastguard Worker         (elInfo.elType == ID_LFE)) {
654*e5436536SAndroid Build Coastguard Worker       /* for ( all sub frames ) ... */
655*e5436536SAndroid Build Coastguard Worker       FDKaacEnc_DistributeBits(
656*e5436536SAndroid Build Coastguard Worker           hQC->hAdjThr, hQC->hAdjThr->adjThrStateElem[i],
657*e5436536SAndroid Build Coastguard Worker           psyOut[0]->psyOutElement[i]->psyOutChannel, &qcElement[0][i]->peData,
658*e5436536SAndroid Build Coastguard Worker           &qcElement[0][i]->grantedPe, &qcElement[0][i]->grantedPeCorr,
659*e5436536SAndroid Build Coastguard Worker           nChannels, psyOut[0]->psyOutElement[i]->commonWindow,
660*e5436536SAndroid Build Coastguard Worker           qcElement[0][i]->grantedDynBits, hQC->elementBits[i]->bitResLevelEl,
661*e5436536SAndroid Build Coastguard Worker           hQC->elementBits[i]->maxBitResBitsEl, hQC->maxBitFac,
662*e5436536SAndroid Build Coastguard Worker           hQC->bitResMode);
663*e5436536SAndroid Build Coastguard Worker 
664*e5436536SAndroid Build Coastguard Worker       *totalAvailableBits += hQC->elementBits[i]->bitResLevelEl;
665*e5436536SAndroid Build Coastguard Worker       /* get total corrected granted PE */
666*e5436536SAndroid Build Coastguard Worker       qcOut[0]->totalGrantedPeCorr += qcElement[0][i]->grantedPeCorr;
667*e5436536SAndroid Build Coastguard Worker     } /*  -end- if(ID_SCE || ID_CPE || ID_LFE) */
668*e5436536SAndroid Build Coastguard Worker 
669*e5436536SAndroid Build Coastguard Worker   } /* -end- element loop */
670*e5436536SAndroid Build Coastguard Worker 
671*e5436536SAndroid Build Coastguard Worker   *totalAvailableBits = fMin(hQC->maxBitsPerFrame, (*totalAvailableBits));
672*e5436536SAndroid Build Coastguard Worker 
673*e5436536SAndroid Build Coastguard Worker   return AAC_ENC_OK;
674*e5436536SAndroid Build Coastguard Worker }
675*e5436536SAndroid Build Coastguard Worker 
676*e5436536SAndroid Build Coastguard Worker ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
FDKaacEnc_updateUsedDynBits(INT * sumDynBitsConsumed,QC_OUT_ELEMENT * qcElement[((8))],CHANNEL_MAPPING * cm)677*e5436536SAndroid Build Coastguard Worker static AAC_ENCODER_ERROR FDKaacEnc_updateUsedDynBits(
678*e5436536SAndroid Build Coastguard Worker     INT* sumDynBitsConsumed, QC_OUT_ELEMENT* qcElement[((8))],
679*e5436536SAndroid Build Coastguard Worker     CHANNEL_MAPPING* cm) {
680*e5436536SAndroid Build Coastguard Worker   INT i;
681*e5436536SAndroid Build Coastguard Worker 
682*e5436536SAndroid Build Coastguard Worker   *sumDynBitsConsumed = 0;
683*e5436536SAndroid Build Coastguard Worker 
684*e5436536SAndroid Build Coastguard Worker   for (i = 0; i < cm->nElements; i++) {
685*e5436536SAndroid Build Coastguard Worker     ELEMENT_INFO elInfo = cm->elInfo[i];
686*e5436536SAndroid Build Coastguard Worker 
687*e5436536SAndroid Build Coastguard Worker     if ((elInfo.elType == ID_SCE) || (elInfo.elType == ID_CPE) ||
688*e5436536SAndroid Build Coastguard Worker         (elInfo.elType == ID_LFE)) {
689*e5436536SAndroid Build Coastguard Worker       /* sum up bits consumed */
690*e5436536SAndroid Build Coastguard Worker       *sumDynBitsConsumed += qcElement[i]->dynBitsUsed;
691*e5436536SAndroid Build Coastguard Worker     } /*  -end- if(ID_SCE || ID_CPE || ID_LFE) */
692*e5436536SAndroid Build Coastguard Worker 
693*e5436536SAndroid Build Coastguard Worker   } /* -end- element loop */
694*e5436536SAndroid Build Coastguard Worker 
695*e5436536SAndroid Build Coastguard Worker   return AAC_ENC_OK;
696*e5436536SAndroid Build Coastguard Worker }
697*e5436536SAndroid Build Coastguard Worker 
FDKaacEnc_getTotalConsumedDynBits(QC_OUT ** qcOut,INT nSubFrames)698*e5436536SAndroid Build Coastguard Worker static INT FDKaacEnc_getTotalConsumedDynBits(QC_OUT** qcOut, INT nSubFrames) {
699*e5436536SAndroid Build Coastguard Worker   INT c, totalBits = 0;
700*e5436536SAndroid Build Coastguard Worker 
701*e5436536SAndroid Build Coastguard Worker   /* sum up bit consumption for all sub frames */
702*e5436536SAndroid Build Coastguard Worker   for (c = 0; c < nSubFrames; c++) {
703*e5436536SAndroid Build Coastguard Worker     /* bit consumption not valid if dynamic bits
704*e5436536SAndroid Build Coastguard Worker        not available in one sub frame */
705*e5436536SAndroid Build Coastguard Worker     if (qcOut[c]->usedDynBits == -1) return -1;
706*e5436536SAndroid Build Coastguard Worker     totalBits += qcOut[c]->usedDynBits;
707*e5436536SAndroid Build Coastguard Worker   }
708*e5436536SAndroid Build Coastguard Worker 
709*e5436536SAndroid Build Coastguard Worker   return totalBits;
710*e5436536SAndroid Build Coastguard Worker }
711*e5436536SAndroid Build Coastguard Worker 
FDKaacEnc_getTotalConsumedBits(QC_OUT ** qcOut,QC_OUT_ELEMENT * qcElement[(1)][((8))],CHANNEL_MAPPING * cm,INT globHdrBits,INT nSubFrames)712*e5436536SAndroid Build Coastguard Worker static INT FDKaacEnc_getTotalConsumedBits(QC_OUT** qcOut,
713*e5436536SAndroid Build Coastguard Worker                                           QC_OUT_ELEMENT* qcElement[(1)][((8))],
714*e5436536SAndroid Build Coastguard Worker                                           CHANNEL_MAPPING* cm, INT globHdrBits,
715*e5436536SAndroid Build Coastguard Worker                                           INT nSubFrames) {
716*e5436536SAndroid Build Coastguard Worker   int c, i;
717*e5436536SAndroid Build Coastguard Worker   int totalUsedBits = 0;
718*e5436536SAndroid Build Coastguard Worker 
719*e5436536SAndroid Build Coastguard Worker   for (c = 0; c < nSubFrames; c++) {
720*e5436536SAndroid Build Coastguard Worker     int dataBits = 0;
721*e5436536SAndroid Build Coastguard Worker     for (i = 0; i < cm->nElements; i++) {
722*e5436536SAndroid Build Coastguard Worker       if ((cm->elInfo[i].elType == ID_SCE) ||
723*e5436536SAndroid Build Coastguard Worker           (cm->elInfo[i].elType == ID_CPE) ||
724*e5436536SAndroid Build Coastguard Worker           (cm->elInfo[i].elType == ID_LFE)) {
725*e5436536SAndroid Build Coastguard Worker         dataBits += qcElement[c][i]->dynBitsUsed +
726*e5436536SAndroid Build Coastguard Worker                     qcElement[c][i]->staticBitsUsed +
727*e5436536SAndroid Build Coastguard Worker                     qcElement[c][i]->extBitsUsed;
728*e5436536SAndroid Build Coastguard Worker       }
729*e5436536SAndroid Build Coastguard Worker     }
730*e5436536SAndroid Build Coastguard Worker     dataBits += qcOut[c]->globalExtBits;
731*e5436536SAndroid Build Coastguard Worker 
732*e5436536SAndroid Build Coastguard Worker     totalUsedBits += (8 - (dataBits) % 8) % 8;
733*e5436536SAndroid Build Coastguard Worker     totalUsedBits += dataBits + globHdrBits; /* header bits for every frame */
734*e5436536SAndroid Build Coastguard Worker   }
735*e5436536SAndroid Build Coastguard Worker   return totalUsedBits;
736*e5436536SAndroid Build Coastguard Worker }
737*e5436536SAndroid Build Coastguard Worker 
FDKaacEnc_BitResRedistribution(QC_STATE * const hQC,const CHANNEL_MAPPING * const cm,const INT avgTotalBits)738*e5436536SAndroid Build Coastguard Worker static AAC_ENCODER_ERROR FDKaacEnc_BitResRedistribution(
739*e5436536SAndroid Build Coastguard Worker     QC_STATE* const hQC, const CHANNEL_MAPPING* const cm,
740*e5436536SAndroid Build Coastguard Worker     const INT avgTotalBits) {
741*e5436536SAndroid Build Coastguard Worker   /* check bitreservoir fill level */
742*e5436536SAndroid Build Coastguard Worker   if (hQC->bitResTot < 0) {
743*e5436536SAndroid Build Coastguard Worker     return AAC_ENC_BITRES_TOO_LOW;
744*e5436536SAndroid Build Coastguard Worker   } else if (hQC->bitResTot > hQC->bitResTotMax) {
745*e5436536SAndroid Build Coastguard Worker     return AAC_ENC_BITRES_TOO_HIGH;
746*e5436536SAndroid Build Coastguard Worker   } else {
747*e5436536SAndroid Build Coastguard Worker     INT i;
748*e5436536SAndroid Build Coastguard Worker     INT totalBits = 0, totalBits_max = 0;
749*e5436536SAndroid Build Coastguard Worker 
750*e5436536SAndroid Build Coastguard Worker     const int totalBitreservoir =
751*e5436536SAndroid Build Coastguard Worker         fMin(hQC->bitResTot, (hQC->maxBitsPerFrame - avgTotalBits));
752*e5436536SAndroid Build Coastguard Worker     const int totalBitreservoirMax =
753*e5436536SAndroid Build Coastguard Worker         fMin(hQC->bitResTotMax, (hQC->maxBitsPerFrame - avgTotalBits));
754*e5436536SAndroid Build Coastguard Worker 
755*e5436536SAndroid Build Coastguard Worker     for (i = (cm->nElements - 1); i >= 0; i--) {
756*e5436536SAndroid Build Coastguard Worker       if ((cm->elInfo[i].elType == ID_SCE) ||
757*e5436536SAndroid Build Coastguard Worker           (cm->elInfo[i].elType == ID_CPE) ||
758*e5436536SAndroid Build Coastguard Worker           (cm->elInfo[i].elType == ID_LFE)) {
759*e5436536SAndroid Build Coastguard Worker         hQC->elementBits[i]->bitResLevelEl =
760*e5436536SAndroid Build Coastguard Worker             fMultI(hQC->elementBits[i]->relativeBitsEl, totalBitreservoir);
761*e5436536SAndroid Build Coastguard Worker         totalBits += hQC->elementBits[i]->bitResLevelEl;
762*e5436536SAndroid Build Coastguard Worker 
763*e5436536SAndroid Build Coastguard Worker         hQC->elementBits[i]->maxBitResBitsEl =
764*e5436536SAndroid Build Coastguard Worker             fMultI(hQC->elementBits[i]->relativeBitsEl, totalBitreservoirMax);
765*e5436536SAndroid Build Coastguard Worker         totalBits_max += hQC->elementBits[i]->maxBitResBitsEl;
766*e5436536SAndroid Build Coastguard Worker       }
767*e5436536SAndroid Build Coastguard Worker     }
768*e5436536SAndroid Build Coastguard Worker     for (i = 0; i < cm->nElements; i++) {
769*e5436536SAndroid Build Coastguard Worker       if ((cm->elInfo[i].elType == ID_SCE) ||
770*e5436536SAndroid Build Coastguard Worker           (cm->elInfo[i].elType == ID_CPE) ||
771*e5436536SAndroid Build Coastguard Worker           (cm->elInfo[i].elType == ID_LFE)) {
772*e5436536SAndroid Build Coastguard Worker         int deltaBits = fMax(totalBitreservoir - totalBits,
773*e5436536SAndroid Build Coastguard Worker                              -hQC->elementBits[i]->bitResLevelEl);
774*e5436536SAndroid Build Coastguard Worker         hQC->elementBits[i]->bitResLevelEl += deltaBits;
775*e5436536SAndroid Build Coastguard Worker         totalBits += deltaBits;
776*e5436536SAndroid Build Coastguard Worker 
777*e5436536SAndroid Build Coastguard Worker         deltaBits = fMax(totalBitreservoirMax - totalBits_max,
778*e5436536SAndroid Build Coastguard Worker                          -hQC->elementBits[i]->maxBitResBitsEl);
779*e5436536SAndroid Build Coastguard Worker         hQC->elementBits[i]->maxBitResBitsEl += deltaBits;
780*e5436536SAndroid Build Coastguard Worker         totalBits_max += deltaBits;
781*e5436536SAndroid Build Coastguard Worker       }
782*e5436536SAndroid Build Coastguard Worker     }
783*e5436536SAndroid Build Coastguard Worker   }
784*e5436536SAndroid Build Coastguard Worker 
785*e5436536SAndroid Build Coastguard Worker   return AAC_ENC_OK;
786*e5436536SAndroid Build Coastguard Worker }
787*e5436536SAndroid Build Coastguard Worker 
FDKaacEnc_QCMain(QC_STATE * RESTRICT hQC,PSY_OUT ** psyOut,QC_OUT ** qcOut,INT avgTotalBits,CHANNEL_MAPPING * cm,const AUDIO_OBJECT_TYPE aot,UINT syntaxFlags,SCHAR epConfig)788*e5436536SAndroid Build Coastguard Worker AAC_ENCODER_ERROR FDKaacEnc_QCMain(QC_STATE* RESTRICT hQC, PSY_OUT** psyOut,
789*e5436536SAndroid Build Coastguard Worker                                    QC_OUT** qcOut, INT avgTotalBits,
790*e5436536SAndroid Build Coastguard Worker                                    CHANNEL_MAPPING* cm,
791*e5436536SAndroid Build Coastguard Worker                                    const AUDIO_OBJECT_TYPE aot,
792*e5436536SAndroid Build Coastguard Worker                                    UINT syntaxFlags, SCHAR epConfig) {
793*e5436536SAndroid Build Coastguard Worker   int i, c;
794*e5436536SAndroid Build Coastguard Worker   AAC_ENCODER_ERROR ErrorStatus = AAC_ENC_OK;
795*e5436536SAndroid Build Coastguard Worker   INT avgTotalDynBits = 0; /* maximal allowed dynamic bits for all frames */
796*e5436536SAndroid Build Coastguard Worker   INT totalAvailableBits = 0;
797*e5436536SAndroid Build Coastguard Worker   INT nSubFrames = 1;
798*e5436536SAndroid Build Coastguard Worker   const INT isCBRAdjustment = (isConstantBitrateMode(hQC->bitrateMode) ||
799*e5436536SAndroid Build Coastguard Worker                                (hQC->bitResMode != AACENC_BR_MODE_FULL))
800*e5436536SAndroid Build Coastguard Worker                                   ? 1
801*e5436536SAndroid Build Coastguard Worker                                   : 0;
802*e5436536SAndroid Build Coastguard Worker 
803*e5436536SAndroid Build Coastguard Worker   /*-------------------------------------------- */
804*e5436536SAndroid Build Coastguard Worker   /* redistribute total bitreservoir to elements */
805*e5436536SAndroid Build Coastguard Worker   ErrorStatus = FDKaacEnc_BitResRedistribution(
806*e5436536SAndroid Build Coastguard Worker       hQC, cm, (isCBRAdjustment == 0) ? hQC->maxBitsPerFrame : avgTotalBits);
807*e5436536SAndroid Build Coastguard Worker   if (ErrorStatus != AAC_ENC_OK) {
808*e5436536SAndroid Build Coastguard Worker     return ErrorStatus;
809*e5436536SAndroid Build Coastguard Worker   }
810*e5436536SAndroid Build Coastguard Worker 
811*e5436536SAndroid Build Coastguard Worker   /*-------------------------------------------- */
812*e5436536SAndroid Build Coastguard Worker   /* fastenc needs one time threshold simulation,
813*e5436536SAndroid Build Coastguard Worker      in case of multiple frames, one more guess has to be calculated */
814*e5436536SAndroid Build Coastguard Worker 
815*e5436536SAndroid Build Coastguard Worker   /*-------------------------------------------- */
816*e5436536SAndroid Build Coastguard Worker   /* helper pointer */
817*e5436536SAndroid Build Coastguard Worker   QC_OUT_ELEMENT* qcElement[(1)][((8))];
818*e5436536SAndroid Build Coastguard Worker 
819*e5436536SAndroid Build Coastguard Worker   /* work on a copy of qcChannel and qcElement */
820*e5436536SAndroid Build Coastguard Worker   for (i = 0; i < cm->nElements; i++) {
821*e5436536SAndroid Build Coastguard Worker     ELEMENT_INFO elInfo = cm->elInfo[i];
822*e5436536SAndroid Build Coastguard Worker 
823*e5436536SAndroid Build Coastguard Worker     if ((elInfo.elType == ID_SCE) || (elInfo.elType == ID_CPE) ||
824*e5436536SAndroid Build Coastguard Worker         (elInfo.elType == ID_LFE)) {
825*e5436536SAndroid Build Coastguard Worker       /* for ( all sub frames ) ... */
826*e5436536SAndroid Build Coastguard Worker       for (c = 0; c < nSubFrames; c++) {
827*e5436536SAndroid Build Coastguard Worker         { qcElement[c][i] = qcOut[c]->qcElement[i]; }
828*e5436536SAndroid Build Coastguard Worker       }
829*e5436536SAndroid Build Coastguard Worker     }
830*e5436536SAndroid Build Coastguard Worker   }
831*e5436536SAndroid Build Coastguard Worker 
832*e5436536SAndroid Build Coastguard Worker   /*-------------------------------------------- */
833*e5436536SAndroid Build Coastguard Worker   /*-------------------------------------------- */
834*e5436536SAndroid Build Coastguard Worker   /* calc granted dynamic bits for sub frame and
835*e5436536SAndroid Build Coastguard Worker      distribute it to each element */
836*e5436536SAndroid Build Coastguard Worker   ErrorStatus = FDKaacEnc_prepareBitDistribution(
837*e5436536SAndroid Build Coastguard Worker       hQC, psyOut, qcOut, cm, qcElement,
838*e5436536SAndroid Build Coastguard Worker       (isCBRAdjustment == 0) ? hQC->maxBitsPerFrame : avgTotalBits,
839*e5436536SAndroid Build Coastguard Worker       &totalAvailableBits, &avgTotalDynBits);
840*e5436536SAndroid Build Coastguard Worker 
841*e5436536SAndroid Build Coastguard Worker   if (ErrorStatus != AAC_ENC_OK) {
842*e5436536SAndroid Build Coastguard Worker     return ErrorStatus;
843*e5436536SAndroid Build Coastguard Worker   }
844*e5436536SAndroid Build Coastguard Worker 
845*e5436536SAndroid Build Coastguard Worker   /* for ( all sub frames ) ... */
846*e5436536SAndroid Build Coastguard Worker   for (c = 0; c < nSubFrames; c++) {
847*e5436536SAndroid Build Coastguard Worker     /* for CBR and VBR mode */
848*e5436536SAndroid Build Coastguard Worker     FDKaacEnc_AdjustThresholds(hQC->hAdjThr, qcElement[c], qcOut[c],
849*e5436536SAndroid Build Coastguard Worker                                psyOut[c]->psyOutElement, isCBRAdjustment, cm);
850*e5436536SAndroid Build Coastguard Worker 
851*e5436536SAndroid Build Coastguard Worker   } /* -end- sub frame counter */
852*e5436536SAndroid Build Coastguard Worker 
853*e5436536SAndroid Build Coastguard Worker   /*-------------------------------------------- */
854*e5436536SAndroid Build Coastguard Worker   INT iterations[(1)][((8))];
855*e5436536SAndroid Build Coastguard Worker   INT chConstraintsFulfilled[(1)][((8))][(2)];
856*e5436536SAndroid Build Coastguard Worker   INT calculateQuant[(1)][((8))][(2)];
857*e5436536SAndroid Build Coastguard Worker   INT constraintsFulfilled[(1)][((8))];
858*e5436536SAndroid Build Coastguard Worker   /*-------------------------------------------- */
859*e5436536SAndroid Build Coastguard Worker 
860*e5436536SAndroid Build Coastguard Worker   /* for ( all sub frames ) ... */
861*e5436536SAndroid Build Coastguard Worker   for (c = 0; c < nSubFrames; c++) {
862*e5436536SAndroid Build Coastguard Worker     for (i = 0; i < cm->nElements; i++) {
863*e5436536SAndroid Build Coastguard Worker       ELEMENT_INFO elInfo = cm->elInfo[i];
864*e5436536SAndroid Build Coastguard Worker       INT ch, nChannels = elInfo.nChannelsInEl;
865*e5436536SAndroid Build Coastguard Worker 
866*e5436536SAndroid Build Coastguard Worker       if ((elInfo.elType == ID_SCE) || (elInfo.elType == ID_CPE) ||
867*e5436536SAndroid Build Coastguard Worker           (elInfo.elType == ID_LFE)) {
868*e5436536SAndroid Build Coastguard Worker         /* Turn thresholds into scalefactors, optimize bit consumption and
869*e5436536SAndroid Build Coastguard Worker          * verify conformance */
870*e5436536SAndroid Build Coastguard Worker         FDKaacEnc_EstimateScaleFactors(
871*e5436536SAndroid Build Coastguard Worker             psyOut[c]->psyOutElement[i]->psyOutChannel,
872*e5436536SAndroid Build Coastguard Worker             qcElement[c][i]->qcOutChannel, hQC->invQuant, hQC->dZoneQuantEnable,
873*e5436536SAndroid Build Coastguard Worker             cm->elInfo[i].nChannelsInEl);
874*e5436536SAndroid Build Coastguard Worker 
875*e5436536SAndroid Build Coastguard Worker         /*-------------------------------------------- */
876*e5436536SAndroid Build Coastguard Worker         constraintsFulfilled[c][i] = 1;
877*e5436536SAndroid Build Coastguard Worker         iterations[c][i] = 0;
878*e5436536SAndroid Build Coastguard Worker 
879*e5436536SAndroid Build Coastguard Worker         for (ch = 0; ch < nChannels; ch++) {
880*e5436536SAndroid Build Coastguard Worker           chConstraintsFulfilled[c][i][ch] = 1;
881*e5436536SAndroid Build Coastguard Worker           calculateQuant[c][i][ch] = 1;
882*e5436536SAndroid Build Coastguard Worker         }
883*e5436536SAndroid Build Coastguard Worker 
884*e5436536SAndroid Build Coastguard Worker         /*-------------------------------------------- */
885*e5436536SAndroid Build Coastguard Worker 
886*e5436536SAndroid Build Coastguard Worker       } /*  -end- if(ID_SCE || ID_CPE || ID_LFE) */
887*e5436536SAndroid Build Coastguard Worker 
888*e5436536SAndroid Build Coastguard Worker     } /* -end- element loop */
889*e5436536SAndroid Build Coastguard Worker 
890*e5436536SAndroid Build Coastguard Worker     qcOut[c]->usedDynBits = -1;
891*e5436536SAndroid Build Coastguard Worker 
892*e5436536SAndroid Build Coastguard Worker   } /* -end- sub frame counter */
893*e5436536SAndroid Build Coastguard Worker 
894*e5436536SAndroid Build Coastguard Worker   INT quantizationDone = 0;
895*e5436536SAndroid Build Coastguard Worker   INT sumDynBitsConsumedTotal = 0;
896*e5436536SAndroid Build Coastguard Worker   INT decreaseBitConsumption = -1; /* no direction yet! */
897*e5436536SAndroid Build Coastguard Worker 
898*e5436536SAndroid Build Coastguard Worker   /*-------------------------------------------- */
899*e5436536SAndroid Build Coastguard Worker   /* -start- Quantization loop ...               */
900*e5436536SAndroid Build Coastguard Worker   /*-------------------------------------------- */
901*e5436536SAndroid Build Coastguard Worker   do /* until max allowed bits per frame and maxDynBits!=-1*/
902*e5436536SAndroid Build Coastguard Worker   {
903*e5436536SAndroid Build Coastguard Worker     quantizationDone = 0;
904*e5436536SAndroid Build Coastguard Worker 
905*e5436536SAndroid Build Coastguard Worker     c = 0; /* get frame to process */
906*e5436536SAndroid Build Coastguard Worker 
907*e5436536SAndroid Build Coastguard Worker     for (i = 0; i < cm->nElements; i++) {
908*e5436536SAndroid Build Coastguard Worker       ELEMENT_INFO elInfo = cm->elInfo[i];
909*e5436536SAndroid Build Coastguard Worker       INT ch, nChannels = elInfo.nChannelsInEl;
910*e5436536SAndroid Build Coastguard Worker 
911*e5436536SAndroid Build Coastguard Worker       if ((elInfo.elType == ID_SCE) || (elInfo.elType == ID_CPE) ||
912*e5436536SAndroid Build Coastguard Worker           (elInfo.elType == ID_LFE)) {
913*e5436536SAndroid Build Coastguard Worker         do /* until element bits < nChannels*MIN_BUFSIZE_PER_EFF_CHAN */
914*e5436536SAndroid Build Coastguard Worker         {
915*e5436536SAndroid Build Coastguard Worker           do /* until spectral values < MAX_QUANT */
916*e5436536SAndroid Build Coastguard Worker           {
917*e5436536SAndroid Build Coastguard Worker             /*-------------------------------------------- */
918*e5436536SAndroid Build Coastguard Worker             if (!constraintsFulfilled[c][i]) {
919*e5436536SAndroid Build Coastguard Worker               if ((ErrorStatus = FDKaacEnc_reduceBitConsumption(
920*e5436536SAndroid Build Coastguard Worker                        &iterations[c][i], hQC->maxIterations,
921*e5436536SAndroid Build Coastguard Worker                        (decreaseBitConsumption) ? 1 : -1,
922*e5436536SAndroid Build Coastguard Worker                        chConstraintsFulfilled[c][i], calculateQuant[c][i],
923*e5436536SAndroid Build Coastguard Worker                        nChannels, psyOut[c]->psyOutElement[i], qcOut[c],
924*e5436536SAndroid Build Coastguard Worker                        qcElement[c][i], hQC->elementBits[i], aot, syntaxFlags,
925*e5436536SAndroid Build Coastguard Worker                        epConfig)) != AAC_ENC_OK) {
926*e5436536SAndroid Build Coastguard Worker                 return ErrorStatus;
927*e5436536SAndroid Build Coastguard Worker               }
928*e5436536SAndroid Build Coastguard Worker             }
929*e5436536SAndroid Build Coastguard Worker 
930*e5436536SAndroid Build Coastguard Worker             /*-------------------------------------------- */
931*e5436536SAndroid Build Coastguard Worker             /*-------------------------------------------- */
932*e5436536SAndroid Build Coastguard Worker             constraintsFulfilled[c][i] = 1;
933*e5436536SAndroid Build Coastguard Worker 
934*e5436536SAndroid Build Coastguard Worker             /*-------------------------------------------- */
935*e5436536SAndroid Build Coastguard Worker             /* quantize spectrum (per each channel) */
936*e5436536SAndroid Build Coastguard Worker             for (ch = 0; ch < nChannels; ch++) {
937*e5436536SAndroid Build Coastguard Worker               /*-------------------------------------------- */
938*e5436536SAndroid Build Coastguard Worker               chConstraintsFulfilled[c][i][ch] = 1;
939*e5436536SAndroid Build Coastguard Worker 
940*e5436536SAndroid Build Coastguard Worker               /*-------------------------------------------- */
941*e5436536SAndroid Build Coastguard Worker 
942*e5436536SAndroid Build Coastguard Worker               if (calculateQuant[c][i][ch]) {
943*e5436536SAndroid Build Coastguard Worker                 QC_OUT_CHANNEL* qcOutCh = qcElement[c][i]->qcOutChannel[ch];
944*e5436536SAndroid Build Coastguard Worker                 PSY_OUT_CHANNEL* psyOutCh =
945*e5436536SAndroid Build Coastguard Worker                     psyOut[c]->psyOutElement[i]->psyOutChannel[ch];
946*e5436536SAndroid Build Coastguard Worker 
947*e5436536SAndroid Build Coastguard Worker                 calculateQuant[c][i][ch] =
948*e5436536SAndroid Build Coastguard Worker                     0; /* calculate quantization only if necessary */
949*e5436536SAndroid Build Coastguard Worker 
950*e5436536SAndroid Build Coastguard Worker                 /*-------------------------------------------- */
951*e5436536SAndroid Build Coastguard Worker                 FDKaacEnc_QuantizeSpectrum(
952*e5436536SAndroid Build Coastguard Worker                     psyOutCh->sfbCnt, psyOutCh->maxSfbPerGroup,
953*e5436536SAndroid Build Coastguard Worker                     psyOutCh->sfbPerGroup, psyOutCh->sfbOffsets,
954*e5436536SAndroid Build Coastguard Worker                     qcOutCh->mdctSpectrum, qcOutCh->globalGain, qcOutCh->scf,
955*e5436536SAndroid Build Coastguard Worker                     qcOutCh->quantSpec, hQC->dZoneQuantEnable);
956*e5436536SAndroid Build Coastguard Worker 
957*e5436536SAndroid Build Coastguard Worker                 /*-------------------------------------------- */
958*e5436536SAndroid Build Coastguard Worker                 if (FDKaacEnc_calcMaxValueInSfb(
959*e5436536SAndroid Build Coastguard Worker                         psyOutCh->sfbCnt, psyOutCh->maxSfbPerGroup,
960*e5436536SAndroid Build Coastguard Worker                         psyOutCh->sfbPerGroup, psyOutCh->sfbOffsets,
961*e5436536SAndroid Build Coastguard Worker                         qcOutCh->quantSpec,
962*e5436536SAndroid Build Coastguard Worker                         qcOutCh->maxValueInSfb) > MAX_QUANT) {
963*e5436536SAndroid Build Coastguard Worker                   chConstraintsFulfilled[c][i][ch] = 0;
964*e5436536SAndroid Build Coastguard Worker                   constraintsFulfilled[c][i] = 0;
965*e5436536SAndroid Build Coastguard Worker                   /* if quanizted value out of range; increase global gain! */
966*e5436536SAndroid Build Coastguard Worker                   decreaseBitConsumption = 1;
967*e5436536SAndroid Build Coastguard Worker                 }
968*e5436536SAndroid Build Coastguard Worker 
969*e5436536SAndroid Build Coastguard Worker                 /*-------------------------------------------- */
970*e5436536SAndroid Build Coastguard Worker 
971*e5436536SAndroid Build Coastguard Worker               } /* if calculateQuant[c][i][ch] */
972*e5436536SAndroid Build Coastguard Worker 
973*e5436536SAndroid Build Coastguard Worker             } /* channel loop */
974*e5436536SAndroid Build Coastguard Worker 
975*e5436536SAndroid Build Coastguard Worker             /*-------------------------------------------- */
976*e5436536SAndroid Build Coastguard Worker             /* quantize spectrum (per each channel) */
977*e5436536SAndroid Build Coastguard Worker 
978*e5436536SAndroid Build Coastguard Worker             /*-------------------------------------------- */
979*e5436536SAndroid Build Coastguard Worker 
980*e5436536SAndroid Build Coastguard Worker           } while (!constraintsFulfilled[c][i]); /* does not regard bit
981*e5436536SAndroid Build Coastguard Worker                                                     consumption */
982*e5436536SAndroid Build Coastguard Worker 
983*e5436536SAndroid Build Coastguard Worker           /*-------------------------------------------- */
984*e5436536SAndroid Build Coastguard Worker           /*-------------------------------------------- */
985*e5436536SAndroid Build Coastguard Worker           qcElement[c][i]->dynBitsUsed = 0; /* reset dynamic bits */
986*e5436536SAndroid Build Coastguard Worker 
987*e5436536SAndroid Build Coastguard Worker           /* quantization valid in current channel! */
988*e5436536SAndroid Build Coastguard Worker           for (ch = 0; ch < nChannels; ch++) {
989*e5436536SAndroid Build Coastguard Worker             QC_OUT_CHANNEL* qcOutCh = qcElement[c][i]->qcOutChannel[ch];
990*e5436536SAndroid Build Coastguard Worker             PSY_OUT_CHANNEL* psyOutCh =
991*e5436536SAndroid Build Coastguard Worker                 psyOut[c]->psyOutElement[i]->psyOutChannel[ch];
992*e5436536SAndroid Build Coastguard Worker 
993*e5436536SAndroid Build Coastguard Worker             /* count dynamic bits */
994*e5436536SAndroid Build Coastguard Worker             INT chDynBits = FDKaacEnc_dynBitCount(
995*e5436536SAndroid Build Coastguard Worker                 hQC->hBitCounter, qcOutCh->quantSpec, qcOutCh->maxValueInSfb,
996*e5436536SAndroid Build Coastguard Worker                 qcOutCh->scf, psyOutCh->lastWindowSequence, psyOutCh->sfbCnt,
997*e5436536SAndroid Build Coastguard Worker                 psyOutCh->maxSfbPerGroup, psyOutCh->sfbPerGroup,
998*e5436536SAndroid Build Coastguard Worker                 psyOutCh->sfbOffsets, &qcOutCh->sectionData, psyOutCh->noiseNrg,
999*e5436536SAndroid Build Coastguard Worker                 psyOutCh->isBook, psyOutCh->isScale, syntaxFlags);
1000*e5436536SAndroid Build Coastguard Worker 
1001*e5436536SAndroid Build Coastguard Worker             /* sum up dynamic channel bits */
1002*e5436536SAndroid Build Coastguard Worker             qcElement[c][i]->dynBitsUsed += chDynBits;
1003*e5436536SAndroid Build Coastguard Worker           }
1004*e5436536SAndroid Build Coastguard Worker 
1005*e5436536SAndroid Build Coastguard Worker           /* save dynBitsUsed for correction of bits2pe relation */
1006*e5436536SAndroid Build Coastguard Worker           if (hQC->hAdjThr->adjThrStateElem[i]->dynBitsLast == -1) {
1007*e5436536SAndroid Build Coastguard Worker             hQC->hAdjThr->adjThrStateElem[i]->dynBitsLast =
1008*e5436536SAndroid Build Coastguard Worker                 qcElement[c][i]->dynBitsUsed;
1009*e5436536SAndroid Build Coastguard Worker           }
1010*e5436536SAndroid Build Coastguard Worker 
1011*e5436536SAndroid Build Coastguard Worker           /* hold total bit consumption in present element below maximum allowed
1012*e5436536SAndroid Build Coastguard Worker            */
1013*e5436536SAndroid Build Coastguard Worker           if (qcElement[c][i]->dynBitsUsed >
1014*e5436536SAndroid Build Coastguard Worker               ((nChannels * MIN_BUFSIZE_PER_EFF_CHAN) -
1015*e5436536SAndroid Build Coastguard Worker                qcElement[c][i]->staticBitsUsed -
1016*e5436536SAndroid Build Coastguard Worker                qcElement[c][i]->extBitsUsed)) {
1017*e5436536SAndroid Build Coastguard Worker             constraintsFulfilled[c][i] = 0;
1018*e5436536SAndroid Build Coastguard Worker           }
1019*e5436536SAndroid Build Coastguard Worker 
1020*e5436536SAndroid Build Coastguard Worker         } while (!constraintsFulfilled[c][i]);
1021*e5436536SAndroid Build Coastguard Worker 
1022*e5436536SAndroid Build Coastguard Worker       } /*  -end- if(ID_SCE || ID_CPE || ID_LFE) */
1023*e5436536SAndroid Build Coastguard Worker 
1024*e5436536SAndroid Build Coastguard Worker     } /* -end- element loop */
1025*e5436536SAndroid Build Coastguard Worker 
1026*e5436536SAndroid Build Coastguard Worker     /* update dynBits of current subFrame */
1027*e5436536SAndroid Build Coastguard Worker     FDKaacEnc_updateUsedDynBits(&qcOut[c]->usedDynBits, qcElement[c], cm);
1028*e5436536SAndroid Build Coastguard Worker 
1029*e5436536SAndroid Build Coastguard Worker     /* get total consumed bits, dyn bits in all sub frames have to be valid */
1030*e5436536SAndroid Build Coastguard Worker     sumDynBitsConsumedTotal =
1031*e5436536SAndroid Build Coastguard Worker         FDKaacEnc_getTotalConsumedDynBits(qcOut, nSubFrames);
1032*e5436536SAndroid Build Coastguard Worker 
1033*e5436536SAndroid Build Coastguard Worker     if (sumDynBitsConsumedTotal == -1) {
1034*e5436536SAndroid Build Coastguard Worker       quantizationDone = 0; /* bit consumption not valid in all sub frames */
1035*e5436536SAndroid Build Coastguard Worker     } else {
1036*e5436536SAndroid Build Coastguard Worker       int sumBitsConsumedTotal = FDKaacEnc_getTotalConsumedBits(
1037*e5436536SAndroid Build Coastguard Worker           qcOut, qcElement, cm, hQC->globHdrBits, nSubFrames);
1038*e5436536SAndroid Build Coastguard Worker 
1039*e5436536SAndroid Build Coastguard Worker       /* in all frames are valid dynamic bits */
1040*e5436536SAndroid Build Coastguard Worker       if (((sumBitsConsumedTotal < totalAvailableBits) ||
1041*e5436536SAndroid Build Coastguard Worker            sumDynBitsConsumedTotal == 0) &&
1042*e5436536SAndroid Build Coastguard Worker           (decreaseBitConsumption == 1) &&
1043*e5436536SAndroid Build Coastguard Worker           checkMinFrameBitsDemand(qcOut, hQC->minBitsPerFrame, nSubFrames)
1044*e5436536SAndroid Build Coastguard Worker           /*()*/) {
1045*e5436536SAndroid Build Coastguard Worker         quantizationDone = 1; /* exit bit adjustment */
1046*e5436536SAndroid Build Coastguard Worker       }
1047*e5436536SAndroid Build Coastguard Worker       if (sumBitsConsumedTotal > totalAvailableBits &&
1048*e5436536SAndroid Build Coastguard Worker           (decreaseBitConsumption == 0)) {
1049*e5436536SAndroid Build Coastguard Worker         quantizationDone = 0; /* reset! */
1050*e5436536SAndroid Build Coastguard Worker       }
1051*e5436536SAndroid Build Coastguard Worker     }
1052*e5436536SAndroid Build Coastguard Worker 
1053*e5436536SAndroid Build Coastguard Worker     /*-------------------------------------------- */
1054*e5436536SAndroid Build Coastguard Worker 
1055*e5436536SAndroid Build Coastguard Worker     int emergencyIterations = 1;
1056*e5436536SAndroid Build Coastguard Worker     int dynBitsOvershoot = 0;
1057*e5436536SAndroid Build Coastguard Worker 
1058*e5436536SAndroid Build Coastguard Worker     for (c = 0; c < nSubFrames; c++) {
1059*e5436536SAndroid Build Coastguard Worker       for (i = 0; i < cm->nElements; i++) {
1060*e5436536SAndroid Build Coastguard Worker         ELEMENT_INFO elInfo = cm->elInfo[i];
1061*e5436536SAndroid Build Coastguard Worker 
1062*e5436536SAndroid Build Coastguard Worker         if ((elInfo.elType == ID_SCE) || (elInfo.elType == ID_CPE) ||
1063*e5436536SAndroid Build Coastguard Worker             (elInfo.elType == ID_LFE)) {
1064*e5436536SAndroid Build Coastguard Worker           /* iteration limitation */
1065*e5436536SAndroid Build Coastguard Worker           emergencyIterations &=
1066*e5436536SAndroid Build Coastguard Worker               ((iterations[c][i] < hQC->maxIterations) ? 0 : 1);
1067*e5436536SAndroid Build Coastguard Worker         }
1068*e5436536SAndroid Build Coastguard Worker       }
1069*e5436536SAndroid Build Coastguard Worker       /* detection if used dyn bits exceeds the maximal allowed criterion */
1070*e5436536SAndroid Build Coastguard Worker       dynBitsOvershoot |=
1071*e5436536SAndroid Build Coastguard Worker           ((qcOut[c]->usedDynBits > qcOut[c]->maxDynBits) ? 1 : 0);
1072*e5436536SAndroid Build Coastguard Worker     }
1073*e5436536SAndroid Build Coastguard Worker 
1074*e5436536SAndroid Build Coastguard Worker     if (quantizationDone == 0 || dynBitsOvershoot) {
1075*e5436536SAndroid Build Coastguard Worker       int sumBitsConsumedTotal = FDKaacEnc_getTotalConsumedBits(
1076*e5436536SAndroid Build Coastguard Worker           qcOut, qcElement, cm, hQC->globHdrBits, nSubFrames);
1077*e5436536SAndroid Build Coastguard Worker 
1078*e5436536SAndroid Build Coastguard Worker       if ((sumDynBitsConsumedTotal >= avgTotalDynBits) ||
1079*e5436536SAndroid Build Coastguard Worker           (sumDynBitsConsumedTotal == 0)) {
1080*e5436536SAndroid Build Coastguard Worker         quantizationDone = 1;
1081*e5436536SAndroid Build Coastguard Worker       }
1082*e5436536SAndroid Build Coastguard Worker       if (emergencyIterations && (sumBitsConsumedTotal < totalAvailableBits)) {
1083*e5436536SAndroid Build Coastguard Worker         quantizationDone = 1;
1084*e5436536SAndroid Build Coastguard Worker       }
1085*e5436536SAndroid Build Coastguard Worker       if ((sumBitsConsumedTotal > totalAvailableBits) ||
1086*e5436536SAndroid Build Coastguard Worker           !checkMinFrameBitsDemand(qcOut, hQC->minBitsPerFrame, nSubFrames)) {
1087*e5436536SAndroid Build Coastguard Worker         quantizationDone = 0;
1088*e5436536SAndroid Build Coastguard Worker       }
1089*e5436536SAndroid Build Coastguard Worker       if ((sumBitsConsumedTotal < totalAvailableBits) &&
1090*e5436536SAndroid Build Coastguard Worker           checkMinFrameBitsDemand(qcOut, hQC->minBitsPerFrame, nSubFrames)) {
1091*e5436536SAndroid Build Coastguard Worker         decreaseBitConsumption = 0;
1092*e5436536SAndroid Build Coastguard Worker       } else {
1093*e5436536SAndroid Build Coastguard Worker         decreaseBitConsumption = 1;
1094*e5436536SAndroid Build Coastguard Worker       }
1095*e5436536SAndroid Build Coastguard Worker 
1096*e5436536SAndroid Build Coastguard Worker       if (dynBitsOvershoot) {
1097*e5436536SAndroid Build Coastguard Worker         quantizationDone = 0;
1098*e5436536SAndroid Build Coastguard Worker         decreaseBitConsumption = 1;
1099*e5436536SAndroid Build Coastguard Worker       }
1100*e5436536SAndroid Build Coastguard Worker 
1101*e5436536SAndroid Build Coastguard Worker       /* reset constraints fullfilled flags */
1102*e5436536SAndroid Build Coastguard Worker       FDKmemclear(constraintsFulfilled, sizeof(constraintsFulfilled));
1103*e5436536SAndroid Build Coastguard Worker       FDKmemclear(chConstraintsFulfilled, sizeof(chConstraintsFulfilled));
1104*e5436536SAndroid Build Coastguard Worker 
1105*e5436536SAndroid Build Coastguard Worker     } /* quantizationDone */
1106*e5436536SAndroid Build Coastguard Worker 
1107*e5436536SAndroid Build Coastguard Worker   } while (!quantizationDone);
1108*e5436536SAndroid Build Coastguard Worker 
1109*e5436536SAndroid Build Coastguard Worker   /*-------------------------------------------- */
1110*e5436536SAndroid Build Coastguard Worker   /* ... -end- Quantization loop                 */
1111*e5436536SAndroid Build Coastguard Worker   /*-------------------------------------------- */
1112*e5436536SAndroid Build Coastguard Worker 
1113*e5436536SAndroid Build Coastguard Worker   /*-------------------------------------------- */
1114*e5436536SAndroid Build Coastguard Worker   /*-------------------------------------------- */
1115*e5436536SAndroid Build Coastguard Worker 
1116*e5436536SAndroid Build Coastguard Worker   return AAC_ENC_OK;
1117*e5436536SAndroid Build Coastguard Worker }
1118*e5436536SAndroid Build Coastguard Worker 
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)1119*e5436536SAndroid Build Coastguard Worker static AAC_ENCODER_ERROR FDKaacEnc_reduceBitConsumption(
1120*e5436536SAndroid Build Coastguard Worker     int* iterations, const int maxIterations, int gainAdjustment,
1121*e5436536SAndroid Build Coastguard Worker     int* chConstraintsFulfilled, int* calculateQuant, int nChannels,
1122*e5436536SAndroid Build Coastguard Worker     PSY_OUT_ELEMENT* psyOutElement, QC_OUT* qcOut, QC_OUT_ELEMENT* qcOutElement,
1123*e5436536SAndroid Build Coastguard Worker     ELEMENT_BITS* elBits, AUDIO_OBJECT_TYPE aot, UINT syntaxFlags,
1124*e5436536SAndroid Build Coastguard Worker     SCHAR epConfig) {
1125*e5436536SAndroid Build Coastguard Worker   int ch;
1126*e5436536SAndroid Build Coastguard Worker 
1127*e5436536SAndroid Build Coastguard Worker   /** SOLVING PROBLEM **/
1128*e5436536SAndroid Build Coastguard Worker   if ((*iterations) < maxIterations) {
1129*e5436536SAndroid Build Coastguard Worker     /* increase gain (+ next iteration) */
1130*e5436536SAndroid Build Coastguard Worker     for (ch = 0; ch < nChannels; ch++) {
1131*e5436536SAndroid Build Coastguard Worker       if (!chConstraintsFulfilled[ch]) {
1132*e5436536SAndroid Build Coastguard Worker         qcOutElement->qcOutChannel[ch]->globalGain += gainAdjustment;
1133*e5436536SAndroid Build Coastguard Worker         calculateQuant[ch] = 1; /* global gain has changed, recalculate
1134*e5436536SAndroid Build Coastguard Worker                                    quantization in next iteration! */
1135*e5436536SAndroid Build Coastguard Worker       }
1136*e5436536SAndroid Build Coastguard Worker     }
1137*e5436536SAndroid Build Coastguard Worker   } else if ((*iterations) == maxIterations) {
1138*e5436536SAndroid Build Coastguard Worker     if (qcOutElement->dynBitsUsed == 0) {
1139*e5436536SAndroid Build Coastguard Worker       return AAC_ENC_QUANT_ERROR;
1140*e5436536SAndroid Build Coastguard Worker     } else {
1141*e5436536SAndroid Build Coastguard Worker       /* crash recovery */
1142*e5436536SAndroid Build Coastguard Worker       INT bitsToSave = 0;
1143*e5436536SAndroid Build Coastguard Worker       if ((bitsToSave = fixMax(
1144*e5436536SAndroid Build Coastguard Worker                (qcOutElement->dynBitsUsed + 8) -
1145*e5436536SAndroid Build Coastguard Worker                    (elBits->bitResLevelEl + qcOutElement->grantedDynBits),
1146*e5436536SAndroid Build Coastguard Worker                (qcOutElement->dynBitsUsed + qcOutElement->staticBitsUsed + 8) -
1147*e5436536SAndroid Build Coastguard Worker                    (elBits->maxBitsEl))) > 0) {
1148*e5436536SAndroid Build Coastguard Worker         FDKaacEnc_crashRecovery(nChannels, psyOutElement, qcOut, qcOutElement,
1149*e5436536SAndroid Build Coastguard Worker                                 bitsToSave, aot, syntaxFlags, epConfig);
1150*e5436536SAndroid Build Coastguard Worker       } else {
1151*e5436536SAndroid Build Coastguard Worker         for (ch = 0; ch < nChannels; ch++) {
1152*e5436536SAndroid Build Coastguard Worker           qcOutElement->qcOutChannel[ch]->globalGain += 1;
1153*e5436536SAndroid Build Coastguard Worker         }
1154*e5436536SAndroid Build Coastguard Worker       }
1155*e5436536SAndroid Build Coastguard Worker       for (ch = 0; ch < nChannels; ch++) {
1156*e5436536SAndroid Build Coastguard Worker         calculateQuant[ch] = 1;
1157*e5436536SAndroid Build Coastguard Worker       }
1158*e5436536SAndroid Build Coastguard Worker     }
1159*e5436536SAndroid Build Coastguard Worker   } else {
1160*e5436536SAndroid Build Coastguard Worker     /* (*iterations) > maxIterations */
1161*e5436536SAndroid Build Coastguard Worker     return AAC_ENC_QUANT_ERROR;
1162*e5436536SAndroid Build Coastguard Worker   }
1163*e5436536SAndroid Build Coastguard Worker   (*iterations)++;
1164*e5436536SAndroid Build Coastguard Worker 
1165*e5436536SAndroid Build Coastguard Worker   return AAC_ENC_OK;
1166*e5436536SAndroid Build Coastguard Worker }
1167*e5436536SAndroid Build Coastguard Worker 
FDKaacEnc_updateFillBits(CHANNEL_MAPPING * cm,QC_STATE * qcKernel,ELEMENT_BITS * RESTRICT elBits[((8))],QC_OUT ** qcOut)1168*e5436536SAndroid Build Coastguard Worker AAC_ENCODER_ERROR FDKaacEnc_updateFillBits(CHANNEL_MAPPING* cm,
1169*e5436536SAndroid Build Coastguard Worker                                            QC_STATE* qcKernel,
1170*e5436536SAndroid Build Coastguard Worker                                            ELEMENT_BITS* RESTRICT elBits[((8))],
1171*e5436536SAndroid Build Coastguard Worker                                            QC_OUT** qcOut) {
1172*e5436536SAndroid Build Coastguard Worker   switch (qcKernel->bitrateMode) {
1173*e5436536SAndroid Build Coastguard Worker     case QCDATA_BR_MODE_SFR:
1174*e5436536SAndroid Build Coastguard Worker       break;
1175*e5436536SAndroid Build Coastguard Worker 
1176*e5436536SAndroid Build Coastguard Worker     case QCDATA_BR_MODE_FF:
1177*e5436536SAndroid Build Coastguard Worker       break;
1178*e5436536SAndroid Build Coastguard Worker     case QCDATA_BR_MODE_VBR_1:
1179*e5436536SAndroid Build Coastguard Worker     case QCDATA_BR_MODE_VBR_2:
1180*e5436536SAndroid Build Coastguard Worker     case QCDATA_BR_MODE_VBR_3:
1181*e5436536SAndroid Build Coastguard Worker     case QCDATA_BR_MODE_VBR_4:
1182*e5436536SAndroid Build Coastguard Worker     case QCDATA_BR_MODE_VBR_5:
1183*e5436536SAndroid Build Coastguard Worker       qcOut[0]->totFillBits =
1184*e5436536SAndroid Build Coastguard Worker           (qcOut[0]->grantedDynBits - qcOut[0]->usedDynBits) &
1185*e5436536SAndroid Build Coastguard Worker           7; /* precalculate alignment bits */
1186*e5436536SAndroid Build Coastguard Worker       qcOut[0]->totalBits = qcOut[0]->staticBits + qcOut[0]->usedDynBits +
1187*e5436536SAndroid Build Coastguard Worker                             qcOut[0]->totFillBits + qcOut[0]->elementExtBits +
1188*e5436536SAndroid Build Coastguard Worker                             qcOut[0]->globalExtBits;
1189*e5436536SAndroid Build Coastguard Worker       qcOut[0]->totFillBits +=
1190*e5436536SAndroid Build Coastguard Worker           (fixMax(0, qcKernel->minBitsPerFrame - qcOut[0]->totalBits) + 7) & ~7;
1191*e5436536SAndroid Build Coastguard Worker       break;
1192*e5436536SAndroid Build Coastguard Worker     case QCDATA_BR_MODE_CBR:
1193*e5436536SAndroid Build Coastguard Worker     case QCDATA_BR_MODE_INVALID:
1194*e5436536SAndroid Build Coastguard Worker     default:
1195*e5436536SAndroid Build Coastguard Worker       INT bitResSpace = qcKernel->bitResTotMax - qcKernel->bitResTot;
1196*e5436536SAndroid Build Coastguard Worker       /* processing fill-bits */
1197*e5436536SAndroid Build Coastguard Worker       INT deltaBitRes = qcOut[0]->grantedDynBits - qcOut[0]->usedDynBits;
1198*e5436536SAndroid Build Coastguard Worker       qcOut[0]->totFillBits = fixMax(
1199*e5436536SAndroid Build Coastguard Worker           (deltaBitRes & 7), (deltaBitRes - (fixMax(0, bitResSpace - 7) & ~7)));
1200*e5436536SAndroid Build Coastguard Worker       qcOut[0]->totalBits = qcOut[0]->staticBits + qcOut[0]->usedDynBits +
1201*e5436536SAndroid Build Coastguard Worker                             qcOut[0]->totFillBits + qcOut[0]->elementExtBits +
1202*e5436536SAndroid Build Coastguard Worker                             qcOut[0]->globalExtBits;
1203*e5436536SAndroid Build Coastguard Worker       qcOut[0]->totFillBits +=
1204*e5436536SAndroid Build Coastguard Worker           (fixMax(0, qcKernel->minBitsPerFrame - qcOut[0]->totalBits) + 7) & ~7;
1205*e5436536SAndroid Build Coastguard Worker       break;
1206*e5436536SAndroid Build Coastguard Worker   } /* switch (qcKernel->bitrateMode) */
1207*e5436536SAndroid Build Coastguard Worker 
1208*e5436536SAndroid Build Coastguard Worker   return AAC_ENC_OK;
1209*e5436536SAndroid Build Coastguard Worker }
1210*e5436536SAndroid Build Coastguard Worker 
1211*e5436536SAndroid Build Coastguard Worker /*********************************************************************************
1212*e5436536SAndroid Build Coastguard Worker 
1213*e5436536SAndroid Build Coastguard Worker          functionname: FDKaacEnc_calcMaxValueInSfb
1214*e5436536SAndroid Build Coastguard Worker          description:
1215*e5436536SAndroid Build Coastguard Worker          return:
1216*e5436536SAndroid Build Coastguard Worker 
1217*e5436536SAndroid Build Coastguard Worker **********************************************************************************/
1218*e5436536SAndroid Build Coastguard Worker 
FDKaacEnc_calcMaxValueInSfb(INT sfbCnt,INT maxSfbPerGroup,INT sfbPerGroup,INT * RESTRICT sfbOffset,SHORT * RESTRICT quantSpectrum,UINT * RESTRICT maxValue)1219*e5436536SAndroid Build Coastguard Worker static INT FDKaacEnc_calcMaxValueInSfb(INT sfbCnt, INT maxSfbPerGroup,
1220*e5436536SAndroid Build Coastguard Worker                                        INT sfbPerGroup, INT* RESTRICT sfbOffset,
1221*e5436536SAndroid Build Coastguard Worker                                        SHORT* RESTRICT quantSpectrum,
1222*e5436536SAndroid Build Coastguard Worker                                        UINT* RESTRICT maxValue) {
1223*e5436536SAndroid Build Coastguard Worker   INT sfbOffs, sfb;
1224*e5436536SAndroid Build Coastguard Worker   INT maxValueAll = 0;
1225*e5436536SAndroid Build Coastguard Worker 
1226*e5436536SAndroid Build Coastguard Worker   for (sfbOffs = 0; sfbOffs < sfbCnt; sfbOffs += sfbPerGroup)
1227*e5436536SAndroid Build Coastguard Worker     for (sfb = 0; sfb < maxSfbPerGroup; sfb++) {
1228*e5436536SAndroid Build Coastguard Worker       INT line;
1229*e5436536SAndroid Build Coastguard Worker       INT maxThisSfb = 0;
1230*e5436536SAndroid Build Coastguard Worker       for (line = sfbOffset[sfbOffs + sfb]; line < sfbOffset[sfbOffs + sfb + 1];
1231*e5436536SAndroid Build Coastguard Worker            line++) {
1232*e5436536SAndroid Build Coastguard Worker         INT tmp = fixp_abs(quantSpectrum[line]);
1233*e5436536SAndroid Build Coastguard Worker         maxThisSfb = fixMax(tmp, maxThisSfb);
1234*e5436536SAndroid Build Coastguard Worker       }
1235*e5436536SAndroid Build Coastguard Worker 
1236*e5436536SAndroid Build Coastguard Worker       maxValue[sfbOffs + sfb] = maxThisSfb;
1237*e5436536SAndroid Build Coastguard Worker       maxValueAll = fixMax(maxThisSfb, maxValueAll);
1238*e5436536SAndroid Build Coastguard Worker     }
1239*e5436536SAndroid Build Coastguard Worker   return maxValueAll;
1240*e5436536SAndroid Build Coastguard Worker }
1241*e5436536SAndroid Build Coastguard Worker 
1242*e5436536SAndroid Build Coastguard Worker /*********************************************************************************
1243*e5436536SAndroid Build Coastguard Worker 
1244*e5436536SAndroid Build Coastguard Worker          functionname: FDKaacEnc_updateBitres
1245*e5436536SAndroid Build Coastguard Worker          description:
1246*e5436536SAndroid Build Coastguard Worker          return:
1247*e5436536SAndroid Build Coastguard Worker 
1248*e5436536SAndroid Build Coastguard Worker **********************************************************************************/
FDKaacEnc_updateBitres(CHANNEL_MAPPING * cm,QC_STATE * qcKernel,QC_OUT ** qcOut)1249*e5436536SAndroid Build Coastguard Worker void FDKaacEnc_updateBitres(CHANNEL_MAPPING* cm, QC_STATE* qcKernel,
1250*e5436536SAndroid Build Coastguard Worker                             QC_OUT** qcOut) {
1251*e5436536SAndroid Build Coastguard Worker   switch (qcKernel->bitrateMode) {
1252*e5436536SAndroid Build Coastguard Worker     case QCDATA_BR_MODE_VBR_1:
1253*e5436536SAndroid Build Coastguard Worker     case QCDATA_BR_MODE_VBR_2:
1254*e5436536SAndroid Build Coastguard Worker     case QCDATA_BR_MODE_VBR_3:
1255*e5436536SAndroid Build Coastguard Worker     case QCDATA_BR_MODE_VBR_4:
1256*e5436536SAndroid Build Coastguard Worker     case QCDATA_BR_MODE_VBR_5:
1257*e5436536SAndroid Build Coastguard Worker       /* variable bitrate */
1258*e5436536SAndroid Build Coastguard Worker       qcKernel->bitResTot =
1259*e5436536SAndroid Build Coastguard Worker           fMin(qcKernel->maxBitsPerFrame, qcKernel->bitResTotMax);
1260*e5436536SAndroid Build Coastguard Worker       break;
1261*e5436536SAndroid Build Coastguard Worker     case QCDATA_BR_MODE_CBR:
1262*e5436536SAndroid Build Coastguard Worker     case QCDATA_BR_MODE_SFR:
1263*e5436536SAndroid Build Coastguard Worker     case QCDATA_BR_MODE_INVALID:
1264*e5436536SAndroid Build Coastguard Worker     default:
1265*e5436536SAndroid Build Coastguard Worker       int c = 0;
1266*e5436536SAndroid Build Coastguard Worker       /* constant bitrate */
1267*e5436536SAndroid Build Coastguard Worker       {
1268*e5436536SAndroid Build Coastguard Worker         qcKernel->bitResTot += qcOut[c]->grantedDynBits -
1269*e5436536SAndroid Build Coastguard Worker                                (qcOut[c]->usedDynBits + qcOut[c]->totFillBits +
1270*e5436536SAndroid Build Coastguard Worker                                 qcOut[c]->alignBits);
1271*e5436536SAndroid Build Coastguard Worker       }
1272*e5436536SAndroid Build Coastguard Worker       break;
1273*e5436536SAndroid Build Coastguard Worker   }
1274*e5436536SAndroid Build Coastguard Worker }
1275*e5436536SAndroid Build Coastguard Worker 
1276*e5436536SAndroid Build Coastguard Worker /*********************************************************************************
1277*e5436536SAndroid Build Coastguard Worker 
1278*e5436536SAndroid Build Coastguard Worker          functionname: FDKaacEnc_FinalizeBitConsumption
1279*e5436536SAndroid Build Coastguard Worker          description:
1280*e5436536SAndroid Build Coastguard Worker          return:
1281*e5436536SAndroid Build Coastguard Worker 
1282*e5436536SAndroid Build Coastguard Worker **********************************************************************************/
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)1283*e5436536SAndroid Build Coastguard Worker AAC_ENCODER_ERROR FDKaacEnc_FinalizeBitConsumption(
1284*e5436536SAndroid Build Coastguard Worker     CHANNEL_MAPPING* cm, QC_STATE* qcKernel, QC_OUT* qcOut,
1285*e5436536SAndroid Build Coastguard Worker     QC_OUT_ELEMENT** qcElement, HANDLE_TRANSPORTENC hTpEnc,
1286*e5436536SAndroid Build Coastguard Worker     AUDIO_OBJECT_TYPE aot, UINT syntaxFlags, SCHAR epConfig) {
1287*e5436536SAndroid Build Coastguard Worker   QC_OUT_EXTENSION fillExtPayload;
1288*e5436536SAndroid Build Coastguard Worker   INT totFillBits, alignBits;
1289*e5436536SAndroid Build Coastguard Worker 
1290*e5436536SAndroid Build Coastguard Worker   /* Get total consumed bits in AU */
1291*e5436536SAndroid Build Coastguard Worker   qcOut->totalBits = qcOut->staticBits + qcOut->usedDynBits +
1292*e5436536SAndroid Build Coastguard Worker                      qcOut->totFillBits + qcOut->elementExtBits +
1293*e5436536SAndroid Build Coastguard Worker                      qcOut->globalExtBits;
1294*e5436536SAndroid Build Coastguard Worker 
1295*e5436536SAndroid Build Coastguard Worker   if (qcKernel->bitrateMode == QCDATA_BR_MODE_CBR) {
1296*e5436536SAndroid Build Coastguard Worker     /* Now we can get the exact transport bit amount, and hopefully it is equal
1297*e5436536SAndroid Build Coastguard Worker      * to the estimated value */
1298*e5436536SAndroid Build Coastguard Worker     INT exactTpBits = transportEnc_GetStaticBits(hTpEnc, qcOut->totalBits);
1299*e5436536SAndroid Build Coastguard Worker 
1300*e5436536SAndroid Build Coastguard Worker     if (exactTpBits != qcKernel->globHdrBits) {
1301*e5436536SAndroid Build Coastguard Worker       INT diffFillBits = 0;
1302*e5436536SAndroid Build Coastguard Worker 
1303*e5436536SAndroid Build Coastguard Worker       /* How many bits can be take by bitreservoir */
1304*e5436536SAndroid Build Coastguard Worker       const INT bitresSpace =
1305*e5436536SAndroid Build Coastguard Worker           qcKernel->bitResTotMax -
1306*e5436536SAndroid Build Coastguard Worker           (qcKernel->bitResTot +
1307*e5436536SAndroid Build Coastguard Worker            (qcOut->grantedDynBits - (qcOut->usedDynBits + qcOut->totFillBits)));
1308*e5436536SAndroid Build Coastguard Worker 
1309*e5436536SAndroid Build Coastguard Worker       /* Number of bits which can be moved to bitreservoir. */
1310*e5436536SAndroid Build Coastguard Worker       const INT bitsToBitres = qcKernel->globHdrBits - exactTpBits;
1311*e5436536SAndroid Build Coastguard Worker       FDK_ASSERT(bitsToBitres >= 0); /* is always positive */
1312*e5436536SAndroid Build Coastguard Worker 
1313*e5436536SAndroid Build Coastguard Worker       /* If bitreservoir can not take all bits, move ramaining bits to fillbits
1314*e5436536SAndroid Build Coastguard Worker        */
1315*e5436536SAndroid Build Coastguard Worker       diffFillBits = fMax(0, bitsToBitres - bitresSpace);
1316*e5436536SAndroid Build Coastguard Worker 
1317*e5436536SAndroid Build Coastguard Worker       /* Assure previous alignment */
1318*e5436536SAndroid Build Coastguard Worker       diffFillBits = (diffFillBits + 7) & ~7;
1319*e5436536SAndroid Build Coastguard Worker 
1320*e5436536SAndroid Build Coastguard Worker       /* Move as many bits as possible to bitreservoir */
1321*e5436536SAndroid Build Coastguard Worker       qcKernel->bitResTot += (bitsToBitres - diffFillBits);
1322*e5436536SAndroid Build Coastguard Worker 
1323*e5436536SAndroid Build Coastguard Worker       /* Write remaing bits as fill bits */
1324*e5436536SAndroid Build Coastguard Worker       qcOut->totFillBits += diffFillBits;
1325*e5436536SAndroid Build Coastguard Worker       qcOut->totalBits += diffFillBits;
1326*e5436536SAndroid Build Coastguard Worker       qcOut->grantedDynBits += diffFillBits;
1327*e5436536SAndroid Build Coastguard Worker 
1328*e5436536SAndroid Build Coastguard Worker       /* Get new header bits */
1329*e5436536SAndroid Build Coastguard Worker       qcKernel->globHdrBits =
1330*e5436536SAndroid Build Coastguard Worker           transportEnc_GetStaticBits(hTpEnc, qcOut->totalBits);
1331*e5436536SAndroid Build Coastguard Worker 
1332*e5436536SAndroid Build Coastguard Worker       if (qcKernel->globHdrBits != exactTpBits) {
1333*e5436536SAndroid Build Coastguard Worker         /* In previous step, fill bits and corresponding total bits were changed
1334*e5436536SAndroid Build Coastguard Worker            when bitreservoir was completely filled. Now we can take the too much
1335*e5436536SAndroid Build Coastguard Worker            taken bits caused by header overhead from bitreservoir.
1336*e5436536SAndroid Build Coastguard Worker          */
1337*e5436536SAndroid Build Coastguard Worker         qcKernel->bitResTot -= (qcKernel->globHdrBits - exactTpBits);
1338*e5436536SAndroid Build Coastguard Worker       }
1339*e5436536SAndroid Build Coastguard Worker     }
1340*e5436536SAndroid Build Coastguard Worker 
1341*e5436536SAndroid Build Coastguard Worker   } /* MODE_CBR */
1342*e5436536SAndroid Build Coastguard Worker 
1343*e5436536SAndroid Build Coastguard Worker   /* Update exact number of consumed header bits. */
1344*e5436536SAndroid Build Coastguard Worker   qcKernel->globHdrBits = transportEnc_GetStaticBits(hTpEnc, qcOut->totalBits);
1345*e5436536SAndroid Build Coastguard Worker 
1346*e5436536SAndroid Build Coastguard Worker   /* Save total fill bits and distribut to alignment and fill bits */
1347*e5436536SAndroid Build Coastguard Worker   totFillBits = qcOut->totFillBits;
1348*e5436536SAndroid Build Coastguard Worker 
1349*e5436536SAndroid Build Coastguard Worker   /* fake a fill extension payload */
1350*e5436536SAndroid Build Coastguard Worker   FDKmemclear(&fillExtPayload, sizeof(QC_OUT_EXTENSION));
1351*e5436536SAndroid Build Coastguard Worker 
1352*e5436536SAndroid Build Coastguard Worker   fillExtPayload.type = EXT_FILL_DATA;
1353*e5436536SAndroid Build Coastguard Worker   fillExtPayload.nPayloadBits = totFillBits;
1354*e5436536SAndroid Build Coastguard Worker 
1355*e5436536SAndroid Build Coastguard Worker   /* ask bitstream encoder how many of that bits can be written in a fill
1356*e5436536SAndroid Build Coastguard Worker    * extension data entity */
1357*e5436536SAndroid Build Coastguard Worker   qcOut->totFillBits = FDKaacEnc_writeExtensionData(NULL, &fillExtPayload, 0, 0,
1358*e5436536SAndroid Build Coastguard Worker                                                     syntaxFlags, aot, epConfig);
1359*e5436536SAndroid Build Coastguard Worker 
1360*e5436536SAndroid Build Coastguard Worker   /* now distribute extra fillbits and alignbits */
1361*e5436536SAndroid Build Coastguard Worker   alignBits =
1362*e5436536SAndroid Build Coastguard Worker       7 - (qcOut->staticBits + qcOut->usedDynBits + qcOut->elementExtBits +
1363*e5436536SAndroid Build Coastguard Worker            qcOut->totFillBits + qcOut->globalExtBits - 1) %
1364*e5436536SAndroid Build Coastguard Worker               8;
1365*e5436536SAndroid Build Coastguard Worker 
1366*e5436536SAndroid Build Coastguard Worker   /* Maybe we could remove this */
1367*e5436536SAndroid Build Coastguard Worker   if (((alignBits + qcOut->totFillBits - totFillBits) == 8) &&
1368*e5436536SAndroid Build Coastguard Worker       (qcOut->totFillBits > 8))
1369*e5436536SAndroid Build Coastguard Worker     qcOut->totFillBits -= 8;
1370*e5436536SAndroid Build Coastguard Worker 
1371*e5436536SAndroid Build Coastguard Worker   qcOut->totalBits = qcOut->staticBits + qcOut->usedDynBits +
1372*e5436536SAndroid Build Coastguard Worker                      qcOut->totFillBits + alignBits + qcOut->elementExtBits +
1373*e5436536SAndroid Build Coastguard Worker                      qcOut->globalExtBits;
1374*e5436536SAndroid Build Coastguard Worker 
1375*e5436536SAndroid Build Coastguard Worker   if ((qcOut->totalBits > qcKernel->maxBitsPerFrame) ||
1376*e5436536SAndroid Build Coastguard Worker       (qcOut->totalBits < qcKernel->minBitsPerFrame)) {
1377*e5436536SAndroid Build Coastguard Worker     return AAC_ENC_QUANT_ERROR;
1378*e5436536SAndroid Build Coastguard Worker   }
1379*e5436536SAndroid Build Coastguard Worker 
1380*e5436536SAndroid Build Coastguard Worker   qcOut->alignBits = alignBits;
1381*e5436536SAndroid Build Coastguard Worker 
1382*e5436536SAndroid Build Coastguard Worker   return AAC_ENC_OK;
1383*e5436536SAndroid Build Coastguard Worker }
1384*e5436536SAndroid Build Coastguard Worker 
1385*e5436536SAndroid Build Coastguard Worker /*********************************************************************************
1386*e5436536SAndroid Build Coastguard Worker 
1387*e5436536SAndroid Build Coastguard Worker          functionname: FDKaacEnc_crashRecovery
1388*e5436536SAndroid Build Coastguard Worker          description:  fulfills constraints by means of brute force...
1389*e5436536SAndroid Build Coastguard Worker                        => bits are saved by cancelling out spectral lines!!
1390*e5436536SAndroid Build Coastguard Worker                           (beginning at the highest frequencies)
1391*e5436536SAndroid Build Coastguard Worker          return:       errorcode
1392*e5436536SAndroid Build Coastguard Worker 
1393*e5436536SAndroid Build Coastguard Worker **********************************************************************************/
1394*e5436536SAndroid Build Coastguard Worker 
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)1395*e5436536SAndroid Build Coastguard Worker static void FDKaacEnc_crashRecovery(INT nChannels,
1396*e5436536SAndroid Build Coastguard Worker                                     PSY_OUT_ELEMENT* psyOutElement,
1397*e5436536SAndroid Build Coastguard Worker                                     QC_OUT* qcOut, QC_OUT_ELEMENT* qcElement,
1398*e5436536SAndroid Build Coastguard Worker                                     INT bitsToSave, AUDIO_OBJECT_TYPE aot,
1399*e5436536SAndroid Build Coastguard Worker                                     UINT syntaxFlags, SCHAR epConfig) {
1400*e5436536SAndroid Build Coastguard Worker   INT ch;
1401*e5436536SAndroid Build Coastguard Worker   INT savedBits = 0;
1402*e5436536SAndroid Build Coastguard Worker   INT sfb, sfbGrp;
1403*e5436536SAndroid Build Coastguard Worker   INT bitsPerScf[(2)][MAX_GROUPED_SFB];
1404*e5436536SAndroid Build Coastguard Worker   INT sectionToScf[(2)][MAX_GROUPED_SFB];
1405*e5436536SAndroid Build Coastguard Worker   INT* sfbOffset;
1406*e5436536SAndroid Build Coastguard Worker   INT sect, statBitsNew;
1407*e5436536SAndroid Build Coastguard Worker   QC_OUT_CHANNEL** qcChannel = qcElement->qcOutChannel;
1408*e5436536SAndroid Build Coastguard Worker   PSY_OUT_CHANNEL** psyChannel = psyOutElement->psyOutChannel;
1409*e5436536SAndroid Build Coastguard Worker 
1410*e5436536SAndroid Build Coastguard Worker   /* create a table which converts frq-bins to bit-demand...    [bitsPerScf] */
1411*e5436536SAndroid Build Coastguard Worker   /* ...and another one which holds the corresponding sections [sectionToScf] */
1412*e5436536SAndroid Build Coastguard Worker   for (ch = 0; ch < nChannels; ch++) {
1413*e5436536SAndroid Build Coastguard Worker     sfbOffset = psyChannel[ch]->sfbOffsets;
1414*e5436536SAndroid Build Coastguard Worker 
1415*e5436536SAndroid Build Coastguard Worker     for (sect = 0; sect < qcChannel[ch]->sectionData.noOfSections; sect++) {
1416*e5436536SAndroid Build Coastguard Worker       INT codeBook = qcChannel[ch]->sectionData.huffsection[sect].codeBook;
1417*e5436536SAndroid Build Coastguard Worker 
1418*e5436536SAndroid Build Coastguard Worker       for (sfb = qcChannel[ch]->sectionData.huffsection[sect].sfbStart;
1419*e5436536SAndroid Build Coastguard Worker            sfb < qcChannel[ch]->sectionData.huffsection[sect].sfbStart +
1420*e5436536SAndroid Build Coastguard Worker                      qcChannel[ch]->sectionData.huffsection[sect].sfbCnt;
1421*e5436536SAndroid Build Coastguard Worker            sfb++) {
1422*e5436536SAndroid Build Coastguard Worker         bitsPerScf[ch][sfb] = 0;
1423*e5436536SAndroid Build Coastguard Worker         if ((codeBook != CODE_BOOK_PNS_NO) /*&&
1424*e5436536SAndroid Build Coastguard Worker              (sfb < (qcChannel[ch]->sectionData.noOfGroups*qcChannel[ch]->sectionData.maxSfbPerGroup))*/) {
1425*e5436536SAndroid Build Coastguard Worker           INT sfbStartLine = sfbOffset[sfb];
1426*e5436536SAndroid Build Coastguard Worker           INT noOfLines = sfbOffset[sfb + 1] - sfbStartLine;
1427*e5436536SAndroid Build Coastguard Worker           bitsPerScf[ch][sfb] = FDKaacEnc_countValues(
1428*e5436536SAndroid Build Coastguard Worker               &(qcChannel[ch]->quantSpec[sfbStartLine]), noOfLines, codeBook);
1429*e5436536SAndroid Build Coastguard Worker         }
1430*e5436536SAndroid Build Coastguard Worker         sectionToScf[ch][sfb] = sect;
1431*e5436536SAndroid Build Coastguard Worker       }
1432*e5436536SAndroid Build Coastguard Worker     }
1433*e5436536SAndroid Build Coastguard Worker   }
1434*e5436536SAndroid Build Coastguard Worker 
1435*e5436536SAndroid Build Coastguard Worker   /* LOWER [maxSfb] IN BOTH CHANNELS!! */
1436*e5436536SAndroid Build Coastguard Worker   /* Attention: in case of stereo: maxSfbL == maxSfbR, GroupingL == GroupingR ;
1437*e5436536SAndroid Build Coastguard Worker    */
1438*e5436536SAndroid Build Coastguard Worker 
1439*e5436536SAndroid Build Coastguard Worker   for (sfb = qcChannel[0]->sectionData.maxSfbPerGroup - 1; sfb >= 0; sfb--) {
1440*e5436536SAndroid Build Coastguard Worker     for (sfbGrp = 0; sfbGrp < psyChannel[0]->sfbCnt;
1441*e5436536SAndroid Build Coastguard Worker          sfbGrp += psyChannel[0]->sfbPerGroup) {
1442*e5436536SAndroid Build Coastguard Worker       for (ch = 0; ch < nChannels; ch++) {
1443*e5436536SAndroid Build Coastguard Worker         sect = sectionToScf[ch][sfbGrp + sfb];
1444*e5436536SAndroid Build Coastguard Worker         qcChannel[ch]->sectionData.huffsection[sect].sfbCnt--;
1445*e5436536SAndroid Build Coastguard Worker         savedBits += bitsPerScf[ch][sfbGrp + sfb];
1446*e5436536SAndroid Build Coastguard Worker 
1447*e5436536SAndroid Build Coastguard Worker         if (qcChannel[ch]->sectionData.huffsection[sect].sfbCnt == 0) {
1448*e5436536SAndroid Build Coastguard Worker           savedBits += (psyChannel[ch]->lastWindowSequence != SHORT_WINDOW)
1449*e5436536SAndroid Build Coastguard Worker                            ? FDKaacEnc_sideInfoTabLong[0]
1450*e5436536SAndroid Build Coastguard Worker                            : FDKaacEnc_sideInfoTabShort[0];
1451*e5436536SAndroid Build Coastguard Worker         }
1452*e5436536SAndroid Build Coastguard Worker       }
1453*e5436536SAndroid Build Coastguard Worker     }
1454*e5436536SAndroid Build Coastguard Worker 
1455*e5436536SAndroid Build Coastguard Worker     /* ...have enough bits been saved? */
1456*e5436536SAndroid Build Coastguard Worker     if (savedBits >= bitsToSave) break;
1457*e5436536SAndroid Build Coastguard Worker 
1458*e5436536SAndroid Build Coastguard Worker   } /* sfb loop */
1459*e5436536SAndroid Build Coastguard Worker 
1460*e5436536SAndroid Build Coastguard Worker   /* if not enough bits saved,
1461*e5436536SAndroid Build Coastguard Worker      clean whole spectrum and remove side info overhead */
1462*e5436536SAndroid Build Coastguard Worker   if (sfb == -1) {
1463*e5436536SAndroid Build Coastguard Worker     sfb = 0;
1464*e5436536SAndroid Build Coastguard Worker   }
1465*e5436536SAndroid Build Coastguard Worker 
1466*e5436536SAndroid Build Coastguard Worker   for (ch = 0; ch < nChannels; ch++) {
1467*e5436536SAndroid Build Coastguard Worker     qcChannel[ch]->sectionData.maxSfbPerGroup = sfb;
1468*e5436536SAndroid Build Coastguard Worker     psyChannel[ch]->maxSfbPerGroup = sfb;
1469*e5436536SAndroid Build Coastguard Worker     /* when no spectrum is coded save tools info in bitstream */
1470*e5436536SAndroid Build Coastguard Worker     if (sfb == 0) {
1471*e5436536SAndroid Build Coastguard Worker       FDKmemclear(&psyChannel[ch]->tnsInfo, sizeof(TNS_INFO));
1472*e5436536SAndroid Build Coastguard Worker       FDKmemclear(&psyOutElement->toolsInfo, sizeof(TOOLSINFO));
1473*e5436536SAndroid Build Coastguard Worker     }
1474*e5436536SAndroid Build Coastguard Worker   }
1475*e5436536SAndroid Build Coastguard Worker   /* dynamic bits will be updated in iteration loop */
1476*e5436536SAndroid Build Coastguard Worker 
1477*e5436536SAndroid Build Coastguard Worker   { /* if stop sfb has changed save bits in side info, e.g. MS or TNS coding */
1478*e5436536SAndroid Build Coastguard Worker     ELEMENT_INFO elInfo;
1479*e5436536SAndroid Build Coastguard Worker 
1480*e5436536SAndroid Build Coastguard Worker     FDKmemclear(&elInfo, sizeof(ELEMENT_INFO));
1481*e5436536SAndroid Build Coastguard Worker     elInfo.nChannelsInEl = nChannels;
1482*e5436536SAndroid Build Coastguard Worker     elInfo.elType = (nChannels == 2) ? ID_CPE : ID_SCE;
1483*e5436536SAndroid Build Coastguard Worker 
1484*e5436536SAndroid Build Coastguard Worker     FDKaacEnc_ChannelElementWrite(NULL, &elInfo, NULL, psyOutElement,
1485*e5436536SAndroid Build Coastguard Worker                                   psyChannel, syntaxFlags, aot, epConfig,
1486*e5436536SAndroid Build Coastguard Worker                                   &statBitsNew, 0);
1487*e5436536SAndroid Build Coastguard Worker   }
1488*e5436536SAndroid Build Coastguard Worker 
1489*e5436536SAndroid Build Coastguard Worker   savedBits = qcElement->staticBitsUsed - statBitsNew;
1490*e5436536SAndroid Build Coastguard Worker 
1491*e5436536SAndroid Build Coastguard Worker   /* update static and dynamic bits */
1492*e5436536SAndroid Build Coastguard Worker   qcElement->staticBitsUsed -= savedBits;
1493*e5436536SAndroid Build Coastguard Worker   qcElement->grantedDynBits += savedBits;
1494*e5436536SAndroid Build Coastguard Worker 
1495*e5436536SAndroid Build Coastguard Worker   qcOut->staticBits -= savedBits;
1496*e5436536SAndroid Build Coastguard Worker   qcOut->grantedDynBits += savedBits;
1497*e5436536SAndroid Build Coastguard Worker   qcOut->maxDynBits += savedBits;
1498*e5436536SAndroid Build Coastguard Worker }
1499*e5436536SAndroid Build Coastguard Worker 
FDKaacEnc_QCClose(QC_STATE ** phQCstate,QC_OUT ** phQC)1500*e5436536SAndroid Build Coastguard Worker void FDKaacEnc_QCClose(QC_STATE** phQCstate, QC_OUT** phQC) {
1501*e5436536SAndroid Build Coastguard Worker   int n, i;
1502*e5436536SAndroid Build Coastguard Worker 
1503*e5436536SAndroid Build Coastguard Worker   if (phQC != NULL) {
1504*e5436536SAndroid Build Coastguard Worker     for (n = 0; n < (1); n++) {
1505*e5436536SAndroid Build Coastguard Worker       if (phQC[n] != NULL) {
1506*e5436536SAndroid Build Coastguard Worker         QC_OUT* hQC = phQC[n];
1507*e5436536SAndroid Build Coastguard Worker         for (i = 0; i < (8); i++) {
1508*e5436536SAndroid Build Coastguard Worker         }
1509*e5436536SAndroid Build Coastguard Worker 
1510*e5436536SAndroid Build Coastguard Worker         for (i = 0; i < ((8)); i++) {
1511*e5436536SAndroid Build Coastguard Worker           if (hQC->qcElement[i]) FreeRam_aacEnc_QCelement(&hQC->qcElement[i]);
1512*e5436536SAndroid Build Coastguard Worker         }
1513*e5436536SAndroid Build Coastguard Worker 
1514*e5436536SAndroid Build Coastguard Worker         FreeRam_aacEnc_QCout(&phQC[n]);
1515*e5436536SAndroid Build Coastguard Worker       }
1516*e5436536SAndroid Build Coastguard Worker     }
1517*e5436536SAndroid Build Coastguard Worker   }
1518*e5436536SAndroid Build Coastguard Worker 
1519*e5436536SAndroid Build Coastguard Worker   if (phQCstate != NULL) {
1520*e5436536SAndroid Build Coastguard Worker     if (*phQCstate != NULL) {
1521*e5436536SAndroid Build Coastguard Worker       QC_STATE* hQCstate = *phQCstate;
1522*e5436536SAndroid Build Coastguard Worker 
1523*e5436536SAndroid Build Coastguard Worker       if (hQCstate->hAdjThr != NULL) FDKaacEnc_AdjThrClose(&hQCstate->hAdjThr);
1524*e5436536SAndroid Build Coastguard Worker 
1525*e5436536SAndroid Build Coastguard Worker       if (hQCstate->hBitCounter != NULL)
1526*e5436536SAndroid Build Coastguard Worker         FDKaacEnc_BCClose(&hQCstate->hBitCounter);
1527*e5436536SAndroid Build Coastguard Worker 
1528*e5436536SAndroid Build Coastguard Worker       for (i = 0; i < ((8)); i++) {
1529*e5436536SAndroid Build Coastguard Worker         if (hQCstate->elementBits[i] != NULL) {
1530*e5436536SAndroid Build Coastguard Worker           FreeRam_aacEnc_ElementBits(&hQCstate->elementBits[i]);
1531*e5436536SAndroid Build Coastguard Worker         }
1532*e5436536SAndroid Build Coastguard Worker       }
1533*e5436536SAndroid Build Coastguard Worker       FreeRam_aacEnc_QCstate(phQCstate);
1534*e5436536SAndroid Build Coastguard Worker     }
1535*e5436536SAndroid Build Coastguard Worker   }
1536*e5436536SAndroid Build Coastguard Worker }
1537