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