xref: /aosp_15_r20/external/aac/libAACenc/src/aacenc.cpp (revision e54365361535b070c2db7374cec45c159c7d0e7a)
1*e5436536SAndroid Build Coastguard Worker /* -----------------------------------------------------------------------------
2*e5436536SAndroid Build Coastguard Worker Software License for The Fraunhofer FDK AAC Codec Library for Android
3*e5436536SAndroid Build Coastguard Worker 
4*e5436536SAndroid Build Coastguard Worker © Copyright  1995 - 2020 Fraunhofer-Gesellschaft zur Förderung der angewandten
5*e5436536SAndroid Build Coastguard Worker Forschung e.V. All rights reserved.
6*e5436536SAndroid Build Coastguard Worker 
7*e5436536SAndroid Build Coastguard Worker  1.    INTRODUCTION
8*e5436536SAndroid Build Coastguard Worker The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
9*e5436536SAndroid Build Coastguard Worker that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
10*e5436536SAndroid Build Coastguard Worker scheme for digital audio. This FDK AAC Codec software is intended to be used on
11*e5436536SAndroid Build Coastguard Worker a wide variety of Android devices.
12*e5436536SAndroid Build Coastguard Worker 
13*e5436536SAndroid Build Coastguard Worker AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
14*e5436536SAndroid Build Coastguard Worker general perceptual audio codecs. AAC-ELD is considered the best-performing
15*e5436536SAndroid Build Coastguard Worker full-bandwidth communications codec by independent studies and is widely
16*e5436536SAndroid Build Coastguard Worker deployed. AAC has been standardized by ISO and IEC as part of the MPEG
17*e5436536SAndroid Build Coastguard Worker specifications.
18*e5436536SAndroid Build Coastguard Worker 
19*e5436536SAndroid Build Coastguard Worker Patent licenses for necessary patent claims for the FDK AAC Codec (including
20*e5436536SAndroid Build Coastguard Worker those of Fraunhofer) may be obtained through Via Licensing
21*e5436536SAndroid Build Coastguard Worker (www.vialicensing.com) or through the respective patent owners individually for
22*e5436536SAndroid Build Coastguard Worker the purpose of encoding or decoding bit streams in products that are compliant
23*e5436536SAndroid Build Coastguard Worker with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
24*e5436536SAndroid Build Coastguard Worker Android devices already license these patent claims through Via Licensing or
25*e5436536SAndroid Build Coastguard Worker directly from the patent owners, and therefore FDK AAC Codec software may
26*e5436536SAndroid Build Coastguard Worker already be covered under those patent licenses when it is used for those
27*e5436536SAndroid Build Coastguard Worker licensed purposes only.
28*e5436536SAndroid Build Coastguard Worker 
29*e5436536SAndroid Build Coastguard Worker Commercially-licensed AAC software libraries, including floating-point versions
30*e5436536SAndroid Build Coastguard Worker with enhanced sound quality, are also available from Fraunhofer. Users are
31*e5436536SAndroid Build Coastguard Worker encouraged to check the Fraunhofer website for additional applications
32*e5436536SAndroid Build Coastguard Worker information and documentation.
33*e5436536SAndroid Build Coastguard Worker 
34*e5436536SAndroid Build Coastguard Worker 2.    COPYRIGHT LICENSE
35*e5436536SAndroid Build Coastguard Worker 
36*e5436536SAndroid Build Coastguard Worker Redistribution and use in source and binary forms, with or without modification,
37*e5436536SAndroid Build Coastguard Worker are permitted without payment of copyright license fees provided that you
38*e5436536SAndroid Build Coastguard Worker satisfy the following conditions:
39*e5436536SAndroid Build Coastguard Worker 
40*e5436536SAndroid Build Coastguard Worker You must retain the complete text of this software license in redistributions of
41*e5436536SAndroid Build Coastguard Worker the FDK AAC Codec or your modifications thereto in source code form.
42*e5436536SAndroid Build Coastguard Worker 
43*e5436536SAndroid Build Coastguard Worker You must retain the complete text of this software license in the documentation
44*e5436536SAndroid Build Coastguard Worker and/or other materials provided with redistributions of the FDK AAC Codec or
45*e5436536SAndroid Build Coastguard Worker your modifications thereto in binary form. You must make available free of
46*e5436536SAndroid Build Coastguard Worker charge copies of the complete source code of the FDK AAC Codec and your
47*e5436536SAndroid Build Coastguard Worker modifications thereto to recipients of copies in binary form.
48*e5436536SAndroid Build Coastguard Worker 
49*e5436536SAndroid Build Coastguard Worker The name of Fraunhofer may not be used to endorse or promote products derived
50*e5436536SAndroid Build Coastguard Worker from this library without prior written permission.
51*e5436536SAndroid Build Coastguard Worker 
52*e5436536SAndroid Build Coastguard Worker You may not charge copyright license fees for anyone to use, copy or distribute
53*e5436536SAndroid Build Coastguard Worker the FDK AAC Codec software or your modifications thereto.
54*e5436536SAndroid Build Coastguard Worker 
55*e5436536SAndroid Build Coastguard Worker Your modified versions of the FDK AAC Codec must carry prominent notices stating
56*e5436536SAndroid Build Coastguard Worker that you changed the software and the date of any change. For modified versions
57*e5436536SAndroid Build Coastguard Worker of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
58*e5436536SAndroid Build Coastguard Worker must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
59*e5436536SAndroid Build Coastguard Worker AAC Codec Library for Android."
60*e5436536SAndroid Build Coastguard Worker 
61*e5436536SAndroid Build Coastguard Worker 3.    NO PATENT LICENSE
62*e5436536SAndroid Build Coastguard Worker 
63*e5436536SAndroid Build Coastguard Worker NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
64*e5436536SAndroid Build Coastguard Worker limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
65*e5436536SAndroid Build Coastguard Worker Fraunhofer provides no warranty of patent non-infringement with respect to this
66*e5436536SAndroid Build Coastguard Worker software.
67*e5436536SAndroid Build Coastguard Worker 
68*e5436536SAndroid Build Coastguard Worker You may use this FDK AAC Codec software or modifications thereto only for
69*e5436536SAndroid Build Coastguard Worker purposes that are authorized by appropriate patent licenses.
70*e5436536SAndroid Build Coastguard Worker 
71*e5436536SAndroid Build Coastguard Worker 4.    DISCLAIMER
72*e5436536SAndroid Build Coastguard Worker 
73*e5436536SAndroid Build Coastguard Worker This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
74*e5436536SAndroid Build Coastguard Worker holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
75*e5436536SAndroid Build Coastguard Worker including but not limited to the implied warranties of merchantability and
76*e5436536SAndroid Build Coastguard Worker fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
77*e5436536SAndroid Build Coastguard Worker CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
78*e5436536SAndroid Build Coastguard Worker or consequential damages, including but not limited to procurement of substitute
79*e5436536SAndroid Build Coastguard Worker goods or services; loss of use, data, or profits, or business interruption,
80*e5436536SAndroid Build Coastguard Worker however caused and on any theory of liability, whether in contract, strict
81*e5436536SAndroid Build Coastguard Worker liability, or tort (including negligence), arising in any way out of the use of
82*e5436536SAndroid Build Coastguard Worker this software, even if advised of the possibility of such damage.
83*e5436536SAndroid Build Coastguard Worker 
84*e5436536SAndroid Build Coastguard Worker 5.    CONTACT INFORMATION
85*e5436536SAndroid Build Coastguard Worker 
86*e5436536SAndroid Build Coastguard Worker Fraunhofer Institute for Integrated Circuits IIS
87*e5436536SAndroid Build Coastguard Worker Attention: Audio and Multimedia Departments - FDK AAC LL
88*e5436536SAndroid Build Coastguard Worker Am Wolfsmantel 33
89*e5436536SAndroid Build Coastguard Worker 91058 Erlangen, Germany
90*e5436536SAndroid Build Coastguard Worker 
91*e5436536SAndroid Build Coastguard Worker www.iis.fraunhofer.de/amm
92*e5436536SAndroid Build Coastguard Worker [email protected]
93*e5436536SAndroid Build Coastguard Worker ----------------------------------------------------------------------------- */
94*e5436536SAndroid Build Coastguard Worker 
95*e5436536SAndroid Build Coastguard Worker /**************************** AAC encoder library ******************************
96*e5436536SAndroid Build Coastguard Worker 
97*e5436536SAndroid Build Coastguard Worker    Author(s):   M. Schug / A. Groeschel
98*e5436536SAndroid Build Coastguard Worker 
99*e5436536SAndroid Build Coastguard Worker    Description: fast aac coder functions
100*e5436536SAndroid Build Coastguard Worker 
101*e5436536SAndroid Build Coastguard Worker *******************************************************************************/
102*e5436536SAndroid Build Coastguard Worker 
103*e5436536SAndroid Build Coastguard Worker #include "aacenc.h"
104*e5436536SAndroid Build Coastguard Worker 
105*e5436536SAndroid Build Coastguard Worker #include "bitenc.h"
106*e5436536SAndroid Build Coastguard Worker #include "interface.h"
107*e5436536SAndroid Build Coastguard Worker #include "psy_configuration.h"
108*e5436536SAndroid Build Coastguard Worker #include "psy_main.h"
109*e5436536SAndroid Build Coastguard Worker #include "qc_main.h"
110*e5436536SAndroid Build Coastguard Worker #include "bandwidth.h"
111*e5436536SAndroid Build Coastguard Worker #include "channel_map.h"
112*e5436536SAndroid Build Coastguard Worker #include "tns_func.h"
113*e5436536SAndroid Build Coastguard Worker #include "aacEnc_ram.h"
114*e5436536SAndroid Build Coastguard Worker 
115*e5436536SAndroid Build Coastguard Worker #include "genericStds.h"
116*e5436536SAndroid Build Coastguard Worker 
117*e5436536SAndroid Build Coastguard Worker #define BITRES_MIN \
118*e5436536SAndroid Build Coastguard Worker   300 /* default threshold for using reduced/disabled bitres mode */
119*e5436536SAndroid Build Coastguard Worker #define BITRES_MAX_LD 4000
120*e5436536SAndroid Build Coastguard Worker #define BITRES_MIN_LD 500
121*e5436536SAndroid Build Coastguard Worker #define BITRATE_MAX_LD 70000 /* Max assumed bitrate for bitres calculation */
122*e5436536SAndroid Build Coastguard Worker #define BITRATE_MIN_LD 12000 /* Min assumed bitrate for bitres calculation */
123*e5436536SAndroid Build Coastguard Worker 
FDKaacEnc_CalcBitsPerFrame(const INT bitRate,const INT frameLength,const INT samplingRate)124*e5436536SAndroid Build Coastguard Worker INT FDKaacEnc_CalcBitsPerFrame(const INT bitRate, const INT frameLength,
125*e5436536SAndroid Build Coastguard Worker                                const INT samplingRate) {
126*e5436536SAndroid Build Coastguard Worker   int shift = 0;
127*e5436536SAndroid Build Coastguard Worker   while ((frameLength & ~((1 << (shift + 1)) - 1)) == frameLength &&
128*e5436536SAndroid Build Coastguard Worker          (samplingRate & ~((1 << (shift + 1)) - 1)) == samplingRate) {
129*e5436536SAndroid Build Coastguard Worker     shift++;
130*e5436536SAndroid Build Coastguard Worker   }
131*e5436536SAndroid Build Coastguard Worker 
132*e5436536SAndroid Build Coastguard Worker   return (bitRate * (frameLength >> shift)) / (samplingRate >> shift);
133*e5436536SAndroid Build Coastguard Worker }
134*e5436536SAndroid Build Coastguard Worker 
FDKaacEnc_CalcBitrate(const INT bitsPerFrame,const INT frameLength,const INT samplingRate)135*e5436536SAndroid Build Coastguard Worker INT FDKaacEnc_CalcBitrate(const INT bitsPerFrame, const INT frameLength,
136*e5436536SAndroid Build Coastguard Worker                           const INT samplingRate) {
137*e5436536SAndroid Build Coastguard Worker   int shift = 0;
138*e5436536SAndroid Build Coastguard Worker   while ((frameLength & ~((1 << (shift + 1)) - 1)) == frameLength &&
139*e5436536SAndroid Build Coastguard Worker          (samplingRate & ~((1 << (shift + 1)) - 1)) == samplingRate) {
140*e5436536SAndroid Build Coastguard Worker     shift++;
141*e5436536SAndroid Build Coastguard Worker   }
142*e5436536SAndroid Build Coastguard Worker 
143*e5436536SAndroid Build Coastguard Worker   return (bitsPerFrame * (samplingRate >> shift)) / (frameLength >> shift);
144*e5436536SAndroid Build Coastguard Worker }
145*e5436536SAndroid Build Coastguard Worker 
146*e5436536SAndroid Build Coastguard Worker static AAC_ENCODER_ERROR FDKaacEnc_InitCheckAncillary(
147*e5436536SAndroid Build Coastguard Worker     INT bitRate, INT framelength, INT ancillaryRate, INT *ancillaryBitsPerFrame,
148*e5436536SAndroid Build Coastguard Worker     INT sampleRate);
149*e5436536SAndroid Build Coastguard Worker 
FDKaacEnc_LimitBitrate(HANDLE_TRANSPORTENC hTpEnc,AUDIO_OBJECT_TYPE aot,INT coreSamplingRate,INT frameLength,INT nChannels,INT nChannelsEff,INT bitRate,INT averageBits,INT * pAverageBitsPerFrame,AACENC_BITRATE_MODE bitrateMode,INT nSubFrames)150*e5436536SAndroid Build Coastguard Worker INT FDKaacEnc_LimitBitrate(HANDLE_TRANSPORTENC hTpEnc, AUDIO_OBJECT_TYPE aot,
151*e5436536SAndroid Build Coastguard Worker                            INT coreSamplingRate, INT frameLength, INT nChannels,
152*e5436536SAndroid Build Coastguard Worker                            INT nChannelsEff, INT bitRate, INT averageBits,
153*e5436536SAndroid Build Coastguard Worker                            INT *pAverageBitsPerFrame,
154*e5436536SAndroid Build Coastguard Worker                            AACENC_BITRATE_MODE bitrateMode, INT nSubFrames) {
155*e5436536SAndroid Build Coastguard Worker   INT transportBits, prevBitRate, averageBitsPerFrame, minBitrate = 0, iter = 0;
156*e5436536SAndroid Build Coastguard Worker   INT minBitsPerFrame = 40 * nChannels;
157*e5436536SAndroid Build Coastguard Worker   if (isLowDelay(aot)) {
158*e5436536SAndroid Build Coastguard Worker     minBitrate = 8000 * nChannelsEff;
159*e5436536SAndroid Build Coastguard Worker   }
160*e5436536SAndroid Build Coastguard Worker 
161*e5436536SAndroid Build Coastguard Worker   do {
162*e5436536SAndroid Build Coastguard Worker     prevBitRate = bitRate;
163*e5436536SAndroid Build Coastguard Worker     averageBitsPerFrame =
164*e5436536SAndroid Build Coastguard Worker         FDKaacEnc_CalcBitsPerFrame(bitRate, frameLength, coreSamplingRate) /
165*e5436536SAndroid Build Coastguard Worker         nSubFrames;
166*e5436536SAndroid Build Coastguard Worker 
167*e5436536SAndroid Build Coastguard Worker     if (pAverageBitsPerFrame != NULL) {
168*e5436536SAndroid Build Coastguard Worker       *pAverageBitsPerFrame = averageBitsPerFrame;
169*e5436536SAndroid Build Coastguard Worker     }
170*e5436536SAndroid Build Coastguard Worker 
171*e5436536SAndroid Build Coastguard Worker     if (hTpEnc != NULL) {
172*e5436536SAndroid Build Coastguard Worker       transportBits = transportEnc_GetStaticBits(hTpEnc, averageBitsPerFrame);
173*e5436536SAndroid Build Coastguard Worker     } else {
174*e5436536SAndroid Build Coastguard Worker       /* Assume some worst case */
175*e5436536SAndroid Build Coastguard Worker       transportBits = 208;
176*e5436536SAndroid Build Coastguard Worker     }
177*e5436536SAndroid Build Coastguard Worker 
178*e5436536SAndroid Build Coastguard Worker     bitRate = fMax(bitRate,
179*e5436536SAndroid Build Coastguard Worker                    fMax(minBitrate,
180*e5436536SAndroid Build Coastguard Worker                         FDKaacEnc_CalcBitrate((minBitsPerFrame + transportBits),
181*e5436536SAndroid Build Coastguard Worker                                               frameLength, coreSamplingRate)));
182*e5436536SAndroid Build Coastguard Worker     FDK_ASSERT(bitRate >= 0);
183*e5436536SAndroid Build Coastguard Worker 
184*e5436536SAndroid Build Coastguard Worker     bitRate = fMin(bitRate, FDKaacEnc_CalcBitrate(
185*e5436536SAndroid Build Coastguard Worker                                 (nChannelsEff * MIN_BUFSIZE_PER_EFF_CHAN),
186*e5436536SAndroid Build Coastguard Worker                                 frameLength, coreSamplingRate));
187*e5436536SAndroid Build Coastguard Worker     FDK_ASSERT(bitRate >= 0);
188*e5436536SAndroid Build Coastguard Worker 
189*e5436536SAndroid Build Coastguard Worker   } while (prevBitRate != bitRate && iter++ < 3);
190*e5436536SAndroid Build Coastguard Worker 
191*e5436536SAndroid Build Coastguard Worker   return bitRate;
192*e5436536SAndroid Build Coastguard Worker }
193*e5436536SAndroid Build Coastguard Worker 
194*e5436536SAndroid Build Coastguard Worker typedef struct {
195*e5436536SAndroid Build Coastguard Worker   AACENC_BITRATE_MODE bitrateMode;
196*e5436536SAndroid Build Coastguard Worker   int chanBitrate[2]; /* mono/stereo settings */
197*e5436536SAndroid Build Coastguard Worker } CONFIG_TAB_ENTRY_VBR;
198*e5436536SAndroid Build Coastguard Worker 
199*e5436536SAndroid Build Coastguard Worker static const CONFIG_TAB_ENTRY_VBR configTabVBR[] = {
200*e5436536SAndroid Build Coastguard Worker     {AACENC_BR_MODE_CBR, {0, 0}},
201*e5436536SAndroid Build Coastguard Worker     {AACENC_BR_MODE_VBR_1, {32000, 20000}},
202*e5436536SAndroid Build Coastguard Worker     {AACENC_BR_MODE_VBR_2, {40000, 32000}},
203*e5436536SAndroid Build Coastguard Worker     {AACENC_BR_MODE_VBR_3, {56000, 48000}},
204*e5436536SAndroid Build Coastguard Worker     {AACENC_BR_MODE_VBR_4, {72000, 64000}},
205*e5436536SAndroid Build Coastguard Worker     {AACENC_BR_MODE_VBR_5, {112000, 96000}}};
206*e5436536SAndroid Build Coastguard Worker 
207*e5436536SAndroid Build Coastguard Worker /*-----------------------------------------------------------------------------
208*e5436536SAndroid Build Coastguard Worker 
209*e5436536SAndroid Build Coastguard Worker      functionname: FDKaacEnc_GetVBRBitrate
210*e5436536SAndroid Build Coastguard Worker      description:  Get VBR bitrate from vbr quality
211*e5436536SAndroid Build Coastguard Worker      input params: int vbrQuality (VBR0, VBR1, VBR2)
212*e5436536SAndroid Build Coastguard Worker                    channelMode
213*e5436536SAndroid Build Coastguard Worker      returns:      vbr bitrate
214*e5436536SAndroid Build Coastguard Worker 
215*e5436536SAndroid Build Coastguard Worker  ------------------------------------------------------------------------------*/
FDKaacEnc_GetVBRBitrate(AACENC_BITRATE_MODE bitrateMode,CHANNEL_MODE channelMode)216*e5436536SAndroid Build Coastguard Worker INT FDKaacEnc_GetVBRBitrate(AACENC_BITRATE_MODE bitrateMode,
217*e5436536SAndroid Build Coastguard Worker                             CHANNEL_MODE channelMode) {
218*e5436536SAndroid Build Coastguard Worker   INT bitrate = 0;
219*e5436536SAndroid Build Coastguard Worker   INT monoStereoMode = 0; /* default mono */
220*e5436536SAndroid Build Coastguard Worker 
221*e5436536SAndroid Build Coastguard Worker   if (FDKaacEnc_GetMonoStereoMode(channelMode) == EL_MODE_STEREO) {
222*e5436536SAndroid Build Coastguard Worker     monoStereoMode = 1;
223*e5436536SAndroid Build Coastguard Worker   }
224*e5436536SAndroid Build Coastguard Worker 
225*e5436536SAndroid Build Coastguard Worker   switch (bitrateMode) {
226*e5436536SAndroid Build Coastguard Worker     case AACENC_BR_MODE_VBR_1:
227*e5436536SAndroid Build Coastguard Worker     case AACENC_BR_MODE_VBR_2:
228*e5436536SAndroid Build Coastguard Worker     case AACENC_BR_MODE_VBR_3:
229*e5436536SAndroid Build Coastguard Worker     case AACENC_BR_MODE_VBR_4:
230*e5436536SAndroid Build Coastguard Worker     case AACENC_BR_MODE_VBR_5:
231*e5436536SAndroid Build Coastguard Worker       bitrate = configTabVBR[bitrateMode].chanBitrate[monoStereoMode];
232*e5436536SAndroid Build Coastguard Worker       break;
233*e5436536SAndroid Build Coastguard Worker     case AACENC_BR_MODE_INVALID:
234*e5436536SAndroid Build Coastguard Worker     case AACENC_BR_MODE_CBR:
235*e5436536SAndroid Build Coastguard Worker     case AACENC_BR_MODE_SFR:
236*e5436536SAndroid Build Coastguard Worker     case AACENC_BR_MODE_FF:
237*e5436536SAndroid Build Coastguard Worker     default:
238*e5436536SAndroid Build Coastguard Worker       bitrate = 0;
239*e5436536SAndroid Build Coastguard Worker       break;
240*e5436536SAndroid Build Coastguard Worker   }
241*e5436536SAndroid Build Coastguard Worker 
242*e5436536SAndroid Build Coastguard Worker   /* convert channel bitrate to overall bitrate*/
243*e5436536SAndroid Build Coastguard Worker   bitrate *= FDKaacEnc_GetChannelModeConfiguration(channelMode)->nChannelsEff;
244*e5436536SAndroid Build Coastguard Worker 
245*e5436536SAndroid Build Coastguard Worker   return bitrate;
246*e5436536SAndroid Build Coastguard Worker }
247*e5436536SAndroid Build Coastguard Worker 
248*e5436536SAndroid Build Coastguard Worker /*-----------------------------------------------------------------------------
249*e5436536SAndroid Build Coastguard Worker 
250*e5436536SAndroid Build Coastguard Worker     functionname: FDKaacEnc_AdjustVBRBitrateMode
251*e5436536SAndroid Build Coastguard Worker     description:  Adjust bitrate mode to given bitrate parameter
252*e5436536SAndroid Build Coastguard Worker     input params: int vbrQuality (VBR0, VBR1, VBR2)
253*e5436536SAndroid Build Coastguard Worker                   bitrate
254*e5436536SAndroid Build Coastguard Worker                   channelMode
255*e5436536SAndroid Build Coastguard Worker     returns:      vbr bitrate mode
256*e5436536SAndroid Build Coastguard Worker 
257*e5436536SAndroid Build Coastguard Worker  ------------------------------------------------------------------------------*/
FDKaacEnc_AdjustVBRBitrateMode(AACENC_BITRATE_MODE bitrateMode,INT bitrate,CHANNEL_MODE channelMode)258*e5436536SAndroid Build Coastguard Worker AACENC_BITRATE_MODE FDKaacEnc_AdjustVBRBitrateMode(
259*e5436536SAndroid Build Coastguard Worker     AACENC_BITRATE_MODE bitrateMode, INT bitrate, CHANNEL_MODE channelMode) {
260*e5436536SAndroid Build Coastguard Worker   AACENC_BITRATE_MODE newBitrateMode = bitrateMode;
261*e5436536SAndroid Build Coastguard Worker 
262*e5436536SAndroid Build Coastguard Worker   if (bitrate != -1) {
263*e5436536SAndroid Build Coastguard Worker     const INT monoStereoMode =
264*e5436536SAndroid Build Coastguard Worker         (FDKaacEnc_GetMonoStereoMode(channelMode) == EL_MODE_STEREO) ? 1 : 0;
265*e5436536SAndroid Build Coastguard Worker     const INT nChannelsEff =
266*e5436536SAndroid Build Coastguard Worker         FDKaacEnc_GetChannelModeConfiguration(channelMode)->nChannelsEff;
267*e5436536SAndroid Build Coastguard Worker     newBitrateMode = AACENC_BR_MODE_INVALID;
268*e5436536SAndroid Build Coastguard Worker 
269*e5436536SAndroid Build Coastguard Worker     for (int idx = (int)(sizeof(configTabVBR) / sizeof(*configTabVBR)) - 1;
270*e5436536SAndroid Build Coastguard Worker          idx >= 0; idx--) {
271*e5436536SAndroid Build Coastguard Worker       if (bitrate >=
272*e5436536SAndroid Build Coastguard Worker           configTabVBR[idx].chanBitrate[monoStereoMode] * nChannelsEff) {
273*e5436536SAndroid Build Coastguard Worker         if (configTabVBR[idx].chanBitrate[monoStereoMode] * nChannelsEff <
274*e5436536SAndroid Build Coastguard Worker             FDKaacEnc_GetVBRBitrate(bitrateMode, channelMode)) {
275*e5436536SAndroid Build Coastguard Worker           newBitrateMode = configTabVBR[idx].bitrateMode;
276*e5436536SAndroid Build Coastguard Worker         } else {
277*e5436536SAndroid Build Coastguard Worker           newBitrateMode = bitrateMode;
278*e5436536SAndroid Build Coastguard Worker         }
279*e5436536SAndroid Build Coastguard Worker         break;
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   return AACENC_BR_MODE_IS_VBR(newBitrateMode) ? newBitrateMode
285*e5436536SAndroid Build Coastguard Worker                                                : AACENC_BR_MODE_INVALID;
286*e5436536SAndroid Build Coastguard Worker }
287*e5436536SAndroid Build Coastguard Worker 
288*e5436536SAndroid Build Coastguard Worker /**
289*e5436536SAndroid Build Coastguard Worker  * \brief  Convert encoder bitreservoir value for transport library.
290*e5436536SAndroid Build Coastguard Worker  *
291*e5436536SAndroid Build Coastguard Worker  * \param hAacEnc               Encoder handle
292*e5436536SAndroid Build Coastguard Worker  *
293*e5436536SAndroid Build Coastguard Worker  * \return  Corrected bitreservoir level used in transport library.
294*e5436536SAndroid Build Coastguard Worker  */
FDKaacEnc_EncBitresToTpBitres(const HANDLE_AAC_ENC hAacEnc)295*e5436536SAndroid Build Coastguard Worker static INT FDKaacEnc_EncBitresToTpBitres(const HANDLE_AAC_ENC hAacEnc) {
296*e5436536SAndroid Build Coastguard Worker   INT transportBitreservoir = 0;
297*e5436536SAndroid Build Coastguard Worker 
298*e5436536SAndroid Build Coastguard Worker   switch (hAacEnc->bitrateMode) {
299*e5436536SAndroid Build Coastguard Worker     case AACENC_BR_MODE_CBR:
300*e5436536SAndroid Build Coastguard Worker       transportBitreservoir =
301*e5436536SAndroid Build Coastguard Worker           hAacEnc->qcKernel->bitResTot; /* encoder bitreservoir level */
302*e5436536SAndroid Build Coastguard Worker       break;
303*e5436536SAndroid Build Coastguard Worker     case AACENC_BR_MODE_VBR_1:
304*e5436536SAndroid Build Coastguard Worker     case AACENC_BR_MODE_VBR_2:
305*e5436536SAndroid Build Coastguard Worker     case AACENC_BR_MODE_VBR_3:
306*e5436536SAndroid Build Coastguard Worker     case AACENC_BR_MODE_VBR_4:
307*e5436536SAndroid Build Coastguard Worker     case AACENC_BR_MODE_VBR_5:
308*e5436536SAndroid Build Coastguard Worker       transportBitreservoir = FDK_INT_MAX; /* signal variable bitrate */
309*e5436536SAndroid Build Coastguard Worker       break;
310*e5436536SAndroid Build Coastguard Worker     case AACENC_BR_MODE_SFR:
311*e5436536SAndroid Build Coastguard Worker       transportBitreservoir = 0; /* super framing and fixed framing */
312*e5436536SAndroid Build Coastguard Worker       break;                     /* without bitreservoir signaling */
313*e5436536SAndroid Build Coastguard Worker     default:
314*e5436536SAndroid Build Coastguard Worker     case AACENC_BR_MODE_INVALID:
315*e5436536SAndroid Build Coastguard Worker       transportBitreservoir = 0; /* invalid configuration*/
316*e5436536SAndroid Build Coastguard Worker   }
317*e5436536SAndroid Build Coastguard Worker 
318*e5436536SAndroid Build Coastguard Worker   if (hAacEnc->config->audioMuxVersion == 2) {
319*e5436536SAndroid Build Coastguard Worker     transportBitreservoir =
320*e5436536SAndroid Build Coastguard Worker         MIN_BUFSIZE_PER_EFF_CHAN * hAacEnc->channelMapping.nChannelsEff;
321*e5436536SAndroid Build Coastguard Worker   }
322*e5436536SAndroid Build Coastguard Worker 
323*e5436536SAndroid Build Coastguard Worker   return transportBitreservoir;
324*e5436536SAndroid Build Coastguard Worker }
325*e5436536SAndroid Build Coastguard Worker 
FDKaacEnc_GetBitReservoirState(const HANDLE_AAC_ENC hAacEncoder)326*e5436536SAndroid Build Coastguard Worker INT FDKaacEnc_GetBitReservoirState(const HANDLE_AAC_ENC hAacEncoder) {
327*e5436536SAndroid Build Coastguard Worker   return FDKaacEnc_EncBitresToTpBitres(hAacEncoder);
328*e5436536SAndroid Build Coastguard Worker }
329*e5436536SAndroid Build Coastguard Worker 
330*e5436536SAndroid Build Coastguard Worker /*-----------------------------------------------------------------------------
331*e5436536SAndroid Build Coastguard Worker 
332*e5436536SAndroid Build Coastguard Worker      functionname: FDKaacEnc_AacInitDefaultConfig
333*e5436536SAndroid Build Coastguard Worker      description:  gives reasonable default configuration
334*e5436536SAndroid Build Coastguard Worker      returns:      ---
335*e5436536SAndroid Build Coastguard Worker 
336*e5436536SAndroid Build Coastguard Worker  ------------------------------------------------------------------------------*/
FDKaacEnc_AacInitDefaultConfig(AACENC_CONFIG * config)337*e5436536SAndroid Build Coastguard Worker void FDKaacEnc_AacInitDefaultConfig(AACENC_CONFIG *config) {
338*e5436536SAndroid Build Coastguard Worker   /* make the preinitialization of the structs flexible */
339*e5436536SAndroid Build Coastguard Worker   FDKmemclear(config, sizeof(AACENC_CONFIG));
340*e5436536SAndroid Build Coastguard Worker 
341*e5436536SAndroid Build Coastguard Worker   /* default ancillary */
342*e5436536SAndroid Build Coastguard Worker   config->anc_Rate = 0;       /* no ancillary data */
343*e5436536SAndroid Build Coastguard Worker   config->ancDataBitRate = 0; /* no additional consumed bitrate */
344*e5436536SAndroid Build Coastguard Worker 
345*e5436536SAndroid Build Coastguard Worker   /* default configurations */
346*e5436536SAndroid Build Coastguard Worker   config->bitRate = -1; /* bitrate must be set*/
347*e5436536SAndroid Build Coastguard Worker   config->averageBits =
348*e5436536SAndroid Build Coastguard Worker       -1; /* instead of bitrate/s we can configure bits/superframe */
349*e5436536SAndroid Build Coastguard Worker   config->bitrateMode =
350*e5436536SAndroid Build Coastguard Worker       AACENC_BR_MODE_CBR;           /* set bitrate mode to constant bitrate */
351*e5436536SAndroid Build Coastguard Worker   config->bandWidth = 0;            /* get bandwidth from table */
352*e5436536SAndroid Build Coastguard Worker   config->useTns = TNS_ENABLE_MASK; /* tns enabled completly */
353*e5436536SAndroid Build Coastguard Worker   config->usePns =
354*e5436536SAndroid Build Coastguard Worker       1; /* depending on channelBitrate this might be set to 0 later */
355*e5436536SAndroid Build Coastguard Worker   config->useIS = 1;        /* Intensity Stereo Configuration */
356*e5436536SAndroid Build Coastguard Worker   config->useMS = 1;        /* MS Stereo tool */
357*e5436536SAndroid Build Coastguard Worker   config->framelength = -1; /* Framesize not configured */
358*e5436536SAndroid Build Coastguard Worker   config->syntaxFlags = 0;  /* default syntax with no specialities */
359*e5436536SAndroid Build Coastguard Worker   config->epConfig = -1;    /* no ER syntax -> no additional error protection */
360*e5436536SAndroid Build Coastguard Worker   config->nSubFrames = 1;   /* default, no sub frames */
361*e5436536SAndroid Build Coastguard Worker   config->channelOrder = CH_ORDER_MPEG; /* Use MPEG channel ordering. */
362*e5436536SAndroid Build Coastguard Worker   config->channelMode = MODE_UNKNOWN;
363*e5436536SAndroid Build Coastguard Worker   config->minBitsPerFrame = -1; /* minum number of bits in each AU */
364*e5436536SAndroid Build Coastguard Worker   config->maxBitsPerFrame = -1; /* minum number of bits in each AU */
365*e5436536SAndroid Build Coastguard Worker   config->audioMuxVersion = -1; /* audio mux version not configured */
366*e5436536SAndroid Build Coastguard Worker   config->downscaleFactor =
367*e5436536SAndroid Build Coastguard Worker       1; /* downscale factor for ELD reduced delay mode, 1 is normal ELD */
368*e5436536SAndroid Build Coastguard Worker }
369*e5436536SAndroid Build Coastguard Worker 
370*e5436536SAndroid Build Coastguard Worker /*---------------------------------------------------------------------------
371*e5436536SAndroid Build Coastguard Worker 
372*e5436536SAndroid Build Coastguard Worker     functionname: FDKaacEnc_Open
373*e5436536SAndroid Build Coastguard Worker     description:  allocate and initialize a new encoder instance
374*e5436536SAndroid Build Coastguard Worker     returns:      error code
375*e5436536SAndroid Build Coastguard Worker 
376*e5436536SAndroid Build Coastguard Worker   ---------------------------------------------------------------------------*/
FDKaacEnc_Open(HANDLE_AAC_ENC * phAacEnc,const INT nElements,const INT nChannels,const INT nSubFrames)377*e5436536SAndroid Build Coastguard Worker AAC_ENCODER_ERROR FDKaacEnc_Open(HANDLE_AAC_ENC *phAacEnc, const INT nElements,
378*e5436536SAndroid Build Coastguard Worker                                  const INT nChannels, const INT nSubFrames) {
379*e5436536SAndroid Build Coastguard Worker   AAC_ENCODER_ERROR ErrorStatus;
380*e5436536SAndroid Build Coastguard Worker   AAC_ENC *hAacEnc = NULL;
381*e5436536SAndroid Build Coastguard Worker   UCHAR *dynamicRAM = NULL;
382*e5436536SAndroid Build Coastguard Worker 
383*e5436536SAndroid Build Coastguard Worker   if (phAacEnc == NULL) {
384*e5436536SAndroid Build Coastguard Worker     return AAC_ENC_INVALID_HANDLE;
385*e5436536SAndroid Build Coastguard Worker   }
386*e5436536SAndroid Build Coastguard Worker 
387*e5436536SAndroid Build Coastguard Worker   /* allocate encoder structure */
388*e5436536SAndroid Build Coastguard Worker   hAacEnc = GetRam_aacEnc_AacEncoder();
389*e5436536SAndroid Build Coastguard Worker   if (hAacEnc == NULL) {
390*e5436536SAndroid Build Coastguard Worker     ErrorStatus = AAC_ENC_NO_MEMORY;
391*e5436536SAndroid Build Coastguard Worker     goto bail;
392*e5436536SAndroid Build Coastguard Worker   }
393*e5436536SAndroid Build Coastguard Worker   FDKmemclear(hAacEnc, sizeof(AAC_ENC));
394*e5436536SAndroid Build Coastguard Worker 
395*e5436536SAndroid Build Coastguard Worker   if (NULL == (hAacEnc->dynamic_RAM = GetAACdynamic_RAM())) {
396*e5436536SAndroid Build Coastguard Worker     ErrorStatus = AAC_ENC_NO_MEMORY;
397*e5436536SAndroid Build Coastguard Worker     goto bail;
398*e5436536SAndroid Build Coastguard Worker   }
399*e5436536SAndroid Build Coastguard Worker   dynamicRAM = (UCHAR *)hAacEnc->dynamic_RAM;
400*e5436536SAndroid Build Coastguard Worker 
401*e5436536SAndroid Build Coastguard Worker   /* allocate the Psy aud Psy Out structure */
402*e5436536SAndroid Build Coastguard Worker   ErrorStatus =
403*e5436536SAndroid Build Coastguard Worker       FDKaacEnc_PsyNew(&hAacEnc->psyKernel, nElements, nChannels, dynamicRAM);
404*e5436536SAndroid Build Coastguard Worker   if (ErrorStatus != AAC_ENC_OK) goto bail;
405*e5436536SAndroid Build Coastguard Worker 
406*e5436536SAndroid Build Coastguard Worker   ErrorStatus = FDKaacEnc_PsyOutNew(hAacEnc->psyOut, nElements, nChannels,
407*e5436536SAndroid Build Coastguard Worker                                     nSubFrames, dynamicRAM);
408*e5436536SAndroid Build Coastguard Worker   if (ErrorStatus != AAC_ENC_OK) goto bail;
409*e5436536SAndroid Build Coastguard Worker 
410*e5436536SAndroid Build Coastguard Worker   /* allocate the Q&C Out structure */
411*e5436536SAndroid Build Coastguard Worker   ErrorStatus = FDKaacEnc_QCOutNew(hAacEnc->qcOut, nElements, nChannels,
412*e5436536SAndroid Build Coastguard Worker                                    nSubFrames, dynamicRAM);
413*e5436536SAndroid Build Coastguard Worker   if (ErrorStatus != AAC_ENC_OK) goto bail;
414*e5436536SAndroid Build Coastguard Worker 
415*e5436536SAndroid Build Coastguard Worker   /* allocate the Q&C kernel */
416*e5436536SAndroid Build Coastguard Worker   ErrorStatus = FDKaacEnc_QCNew(&hAacEnc->qcKernel, nElements, dynamicRAM);
417*e5436536SAndroid Build Coastguard Worker   if (ErrorStatus != AAC_ENC_OK) goto bail;
418*e5436536SAndroid Build Coastguard Worker 
419*e5436536SAndroid Build Coastguard Worker   hAacEnc->maxChannels = nChannels;
420*e5436536SAndroid Build Coastguard Worker   hAacEnc->maxElements = nElements;
421*e5436536SAndroid Build Coastguard Worker   hAacEnc->maxFrames = nSubFrames;
422*e5436536SAndroid Build Coastguard Worker 
423*e5436536SAndroid Build Coastguard Worker bail:
424*e5436536SAndroid Build Coastguard Worker   *phAacEnc = hAacEnc;
425*e5436536SAndroid Build Coastguard Worker   return ErrorStatus;
426*e5436536SAndroid Build Coastguard Worker }
427*e5436536SAndroid Build Coastguard Worker 
FDKaacEnc_Initialize(HANDLE_AAC_ENC hAacEnc,AACENC_CONFIG * config,HANDLE_TRANSPORTENC hTpEnc,ULONG initFlags)428*e5436536SAndroid Build Coastguard Worker AAC_ENCODER_ERROR FDKaacEnc_Initialize(
429*e5436536SAndroid Build Coastguard Worker     HANDLE_AAC_ENC hAacEnc,
430*e5436536SAndroid Build Coastguard Worker     AACENC_CONFIG *config, /* pre-initialized config struct */
431*e5436536SAndroid Build Coastguard Worker     HANDLE_TRANSPORTENC hTpEnc, ULONG initFlags) {
432*e5436536SAndroid Build Coastguard Worker   AAC_ENCODER_ERROR ErrorStatus;
433*e5436536SAndroid Build Coastguard Worker   INT psyBitrate, tnsMask;  // INT profile = 1;
434*e5436536SAndroid Build Coastguard Worker   CHANNEL_MAPPING *cm = NULL;
435*e5436536SAndroid Build Coastguard Worker 
436*e5436536SAndroid Build Coastguard Worker   INT mbfac_e, qbw;
437*e5436536SAndroid Build Coastguard Worker   FIXP_DBL mbfac, bw_ratio;
438*e5436536SAndroid Build Coastguard Worker   QC_INIT qcInit;
439*e5436536SAndroid Build Coastguard Worker   INT averageBitsPerFrame = 0;
440*e5436536SAndroid Build Coastguard Worker   const CHANNEL_MODE prevChannelMode = hAacEnc->encoderMode;
441*e5436536SAndroid Build Coastguard Worker 
442*e5436536SAndroid Build Coastguard Worker   if (config == NULL) return AAC_ENC_INVALID_HANDLE;
443*e5436536SAndroid Build Coastguard Worker 
444*e5436536SAndroid Build Coastguard Worker   /******************* sanity checks *******************/
445*e5436536SAndroid Build Coastguard Worker 
446*e5436536SAndroid Build Coastguard Worker   /* check config structure */
447*e5436536SAndroid Build Coastguard Worker   if (config->nChannels < 1 || config->nChannels > (8)) {
448*e5436536SAndroid Build Coastguard Worker     return AAC_ENC_UNSUPPORTED_CHANNELCONFIG;
449*e5436536SAndroid Build Coastguard Worker   }
450*e5436536SAndroid Build Coastguard Worker 
451*e5436536SAndroid Build Coastguard Worker   /* check sample rate */
452*e5436536SAndroid Build Coastguard Worker   switch (config->sampleRate) {
453*e5436536SAndroid Build Coastguard Worker     case 8000:
454*e5436536SAndroid Build Coastguard Worker     case 11025:
455*e5436536SAndroid Build Coastguard Worker     case 12000:
456*e5436536SAndroid Build Coastguard Worker     case 16000:
457*e5436536SAndroid Build Coastguard Worker     case 22050:
458*e5436536SAndroid Build Coastguard Worker     case 24000:
459*e5436536SAndroid Build Coastguard Worker     case 32000:
460*e5436536SAndroid Build Coastguard Worker     case 44100:
461*e5436536SAndroid Build Coastguard Worker     case 48000:
462*e5436536SAndroid Build Coastguard Worker     case 64000:
463*e5436536SAndroid Build Coastguard Worker     case 88200:
464*e5436536SAndroid Build Coastguard Worker     case 96000:
465*e5436536SAndroid Build Coastguard Worker       break;
466*e5436536SAndroid Build Coastguard Worker     default:
467*e5436536SAndroid Build Coastguard Worker       return AAC_ENC_UNSUPPORTED_SAMPLINGRATE;
468*e5436536SAndroid Build Coastguard Worker   }
469*e5436536SAndroid Build Coastguard Worker 
470*e5436536SAndroid Build Coastguard Worker   /* bitrate has to be set */
471*e5436536SAndroid Build Coastguard Worker   if (config->bitRate == -1) {
472*e5436536SAndroid Build Coastguard Worker     return AAC_ENC_UNSUPPORTED_BITRATE;
473*e5436536SAndroid Build Coastguard Worker   }
474*e5436536SAndroid Build Coastguard Worker 
475*e5436536SAndroid Build Coastguard Worker   /* check bit rate */
476*e5436536SAndroid Build Coastguard Worker 
477*e5436536SAndroid Build Coastguard Worker   if (FDKaacEnc_LimitBitrate(
478*e5436536SAndroid Build Coastguard Worker           hTpEnc, config->audioObjectType, config->sampleRate,
479*e5436536SAndroid Build Coastguard Worker           config->framelength, config->nChannels,
480*e5436536SAndroid Build Coastguard Worker           FDKaacEnc_GetChannelModeConfiguration(config->channelMode)
481*e5436536SAndroid Build Coastguard Worker               ->nChannelsEff,
482*e5436536SAndroid Build Coastguard Worker           config->bitRate, config->averageBits, &averageBitsPerFrame,
483*e5436536SAndroid Build Coastguard Worker           config->bitrateMode, config->nSubFrames) != config->bitRate &&
484*e5436536SAndroid Build Coastguard Worker       !(AACENC_BR_MODE_IS_VBR(config->bitrateMode))) {
485*e5436536SAndroid Build Coastguard Worker     return AAC_ENC_UNSUPPORTED_BITRATE;
486*e5436536SAndroid Build Coastguard Worker   }
487*e5436536SAndroid Build Coastguard Worker 
488*e5436536SAndroid Build Coastguard Worker   if (config->syntaxFlags & AC_ER_VCB11) {
489*e5436536SAndroid Build Coastguard Worker     return AAC_ENC_UNSUPPORTED_ER_FORMAT;
490*e5436536SAndroid Build Coastguard Worker   }
491*e5436536SAndroid Build Coastguard Worker   if (config->syntaxFlags & AC_ER_HCR) {
492*e5436536SAndroid Build Coastguard Worker     return AAC_ENC_UNSUPPORTED_ER_FORMAT;
493*e5436536SAndroid Build Coastguard Worker   }
494*e5436536SAndroid Build Coastguard Worker 
495*e5436536SAndroid Build Coastguard Worker   /* check frame length */
496*e5436536SAndroid Build Coastguard Worker   switch (config->framelength) {
497*e5436536SAndroid Build Coastguard Worker     case 1024:
498*e5436536SAndroid Build Coastguard Worker       if (isLowDelay(config->audioObjectType)) {
499*e5436536SAndroid Build Coastguard Worker         return AAC_ENC_INVALID_FRAME_LENGTH;
500*e5436536SAndroid Build Coastguard Worker       }
501*e5436536SAndroid Build Coastguard Worker       break;
502*e5436536SAndroid Build Coastguard Worker     case 128:
503*e5436536SAndroid Build Coastguard Worker     case 256:
504*e5436536SAndroid Build Coastguard Worker     case 512:
505*e5436536SAndroid Build Coastguard Worker     case 120:
506*e5436536SAndroid Build Coastguard Worker     case 240:
507*e5436536SAndroid Build Coastguard Worker     case 480:
508*e5436536SAndroid Build Coastguard Worker       if (!isLowDelay(config->audioObjectType)) {
509*e5436536SAndroid Build Coastguard Worker         return AAC_ENC_INVALID_FRAME_LENGTH;
510*e5436536SAndroid Build Coastguard Worker       }
511*e5436536SAndroid Build Coastguard Worker       break;
512*e5436536SAndroid Build Coastguard Worker     default:
513*e5436536SAndroid Build Coastguard Worker       return AAC_ENC_INVALID_FRAME_LENGTH;
514*e5436536SAndroid Build Coastguard Worker   }
515*e5436536SAndroid Build Coastguard Worker 
516*e5436536SAndroid Build Coastguard Worker   if (config->anc_Rate != 0) {
517*e5436536SAndroid Build Coastguard Worker     ErrorStatus = FDKaacEnc_InitCheckAncillary(
518*e5436536SAndroid Build Coastguard Worker         config->bitRate, config->framelength, config->anc_Rate,
519*e5436536SAndroid Build Coastguard Worker         &hAacEnc->ancillaryBitsPerFrame, config->sampleRate);
520*e5436536SAndroid Build Coastguard Worker     if (ErrorStatus != AAC_ENC_OK) goto bail;
521*e5436536SAndroid Build Coastguard Worker 
522*e5436536SAndroid Build Coastguard Worker     /* update estimated consumed bitrate */
523*e5436536SAndroid Build Coastguard Worker     config->ancDataBitRate +=
524*e5436536SAndroid Build Coastguard Worker         FDKaacEnc_CalcBitrate(hAacEnc->ancillaryBitsPerFrame,
525*e5436536SAndroid Build Coastguard Worker                               config->framelength, config->sampleRate);
526*e5436536SAndroid Build Coastguard Worker   }
527*e5436536SAndroid Build Coastguard Worker 
528*e5436536SAndroid Build Coastguard Worker   /* maximal allowed DSE bytes in frame */
529*e5436536SAndroid Build Coastguard Worker   config->maxAncBytesPerAU =
530*e5436536SAndroid Build Coastguard Worker       fMin((256), fMax(0, FDKaacEnc_CalcBitsPerFrame(
531*e5436536SAndroid Build Coastguard Worker                               (config->bitRate - (config->nChannels * 8000)),
532*e5436536SAndroid Build Coastguard Worker                               config->framelength, config->sampleRate) >>
533*e5436536SAndroid Build Coastguard Worker                               3));
534*e5436536SAndroid Build Coastguard Worker 
535*e5436536SAndroid Build Coastguard Worker   /* bind config to hAacEnc->config */
536*e5436536SAndroid Build Coastguard Worker   hAacEnc->config = config;
537*e5436536SAndroid Build Coastguard Worker 
538*e5436536SAndroid Build Coastguard Worker   /* set hAacEnc->bitrateMode */
539*e5436536SAndroid Build Coastguard Worker   hAacEnc->bitrateMode = config->bitrateMode;
540*e5436536SAndroid Build Coastguard Worker 
541*e5436536SAndroid Build Coastguard Worker   hAacEnc->encoderMode = config->channelMode;
542*e5436536SAndroid Build Coastguard Worker 
543*e5436536SAndroid Build Coastguard Worker   ErrorStatus = FDKaacEnc_InitChannelMapping(
544*e5436536SAndroid Build Coastguard Worker       hAacEnc->encoderMode, config->channelOrder, &hAacEnc->channelMapping);
545*e5436536SAndroid Build Coastguard Worker   if (ErrorStatus != AAC_ENC_OK) goto bail;
546*e5436536SAndroid Build Coastguard Worker 
547*e5436536SAndroid Build Coastguard Worker   cm = &hAacEnc->channelMapping;
548*e5436536SAndroid Build Coastguard Worker 
549*e5436536SAndroid Build Coastguard Worker   ErrorStatus = FDKaacEnc_DetermineBandWidth(
550*e5436536SAndroid Build Coastguard Worker       config->bandWidth, config->bitRate - config->ancDataBitRate,
551*e5436536SAndroid Build Coastguard Worker       hAacEnc->bitrateMode, config->sampleRate, config->framelength, cm,
552*e5436536SAndroid Build Coastguard Worker       hAacEnc->encoderMode, &hAacEnc->config->bandWidth);
553*e5436536SAndroid Build Coastguard Worker   if (ErrorStatus != AAC_ENC_OK) goto bail;
554*e5436536SAndroid Build Coastguard Worker 
555*e5436536SAndroid Build Coastguard Worker   hAacEnc->bandwidth90dB = (INT)hAacEnc->config->bandWidth;
556*e5436536SAndroid Build Coastguard Worker 
557*e5436536SAndroid Build Coastguard Worker   tnsMask = config->useTns ? TNS_ENABLE_MASK : 0x0;
558*e5436536SAndroid Build Coastguard Worker   psyBitrate = config->bitRate - config->ancDataBitRate;
559*e5436536SAndroid Build Coastguard Worker 
560*e5436536SAndroid Build Coastguard Worker   if ((hAacEnc->encoderMode != prevChannelMode) || (initFlags != 0)) {
561*e5436536SAndroid Build Coastguard Worker     /* Reinitialize psych states in case of channel configuration change ore if
562*e5436536SAndroid Build Coastguard Worker      * full reset requested. */
563*e5436536SAndroid Build Coastguard Worker     ErrorStatus = FDKaacEnc_psyInit(hAacEnc->psyKernel, hAacEnc->psyOut,
564*e5436536SAndroid Build Coastguard Worker                                     hAacEnc->maxFrames, hAacEnc->maxChannels,
565*e5436536SAndroid Build Coastguard Worker                                     config->audioObjectType, cm);
566*e5436536SAndroid Build Coastguard Worker     if (ErrorStatus != AAC_ENC_OK) goto bail;
567*e5436536SAndroid Build Coastguard Worker   }
568*e5436536SAndroid Build Coastguard Worker 
569*e5436536SAndroid Build Coastguard Worker   ErrorStatus = FDKaacEnc_psyMainInit(
570*e5436536SAndroid Build Coastguard Worker       hAacEnc->psyKernel, config->audioObjectType, cm, config->sampleRate,
571*e5436536SAndroid Build Coastguard Worker       config->framelength, psyBitrate, tnsMask, hAacEnc->bandwidth90dB,
572*e5436536SAndroid Build Coastguard Worker       config->usePns, config->useIS, config->useMS, config->syntaxFlags,
573*e5436536SAndroid Build Coastguard Worker       initFlags);
574*e5436536SAndroid Build Coastguard Worker   if (ErrorStatus != AAC_ENC_OK) goto bail;
575*e5436536SAndroid Build Coastguard Worker 
576*e5436536SAndroid Build Coastguard Worker   ErrorStatus = FDKaacEnc_QCOutInit(hAacEnc->qcOut, hAacEnc->maxFrames, cm);
577*e5436536SAndroid Build Coastguard Worker   if (ErrorStatus != AAC_ENC_OK) goto bail;
578*e5436536SAndroid Build Coastguard Worker 
579*e5436536SAndroid Build Coastguard Worker   qcInit.channelMapping = &hAacEnc->channelMapping;
580*e5436536SAndroid Build Coastguard Worker   qcInit.sceCpe = 0;
581*e5436536SAndroid Build Coastguard Worker 
582*e5436536SAndroid Build Coastguard Worker   if (AACENC_BR_MODE_IS_VBR(config->bitrateMode)) {
583*e5436536SAndroid Build Coastguard Worker     qcInit.averageBits = (averageBitsPerFrame + 7) & ~7;
584*e5436536SAndroid Build Coastguard Worker     qcInit.bitRes = MIN_BUFSIZE_PER_EFF_CHAN * cm->nChannelsEff;
585*e5436536SAndroid Build Coastguard Worker     qcInit.maxBits = MIN_BUFSIZE_PER_EFF_CHAN * cm->nChannelsEff;
586*e5436536SAndroid Build Coastguard Worker     qcInit.maxBits = (config->maxBitsPerFrame != -1)
587*e5436536SAndroid Build Coastguard Worker                          ? fixMin(qcInit.maxBits, config->maxBitsPerFrame)
588*e5436536SAndroid Build Coastguard Worker                          : qcInit.maxBits;
589*e5436536SAndroid Build Coastguard Worker     qcInit.maxBits = fixMax(qcInit.maxBits, (averageBitsPerFrame + 7) & ~7);
590*e5436536SAndroid Build Coastguard Worker     qcInit.minBits =
591*e5436536SAndroid Build Coastguard Worker         (config->minBitsPerFrame != -1) ? config->minBitsPerFrame : 0;
592*e5436536SAndroid Build Coastguard Worker     qcInit.minBits = fixMin(qcInit.minBits, averageBitsPerFrame & ~7);
593*e5436536SAndroid Build Coastguard Worker   } else {
594*e5436536SAndroid Build Coastguard Worker     INT bitreservoir = -1; /* default bitreservoir size*/
595*e5436536SAndroid Build Coastguard Worker     if (isLowDelay(config->audioObjectType)) {
596*e5436536SAndroid Build Coastguard Worker       INT brPerChannel = config->bitRate / config->nChannels;
597*e5436536SAndroid Build Coastguard Worker       brPerChannel = fMin(BITRATE_MAX_LD, fMax(BITRATE_MIN_LD, brPerChannel));
598*e5436536SAndroid Build Coastguard Worker 
599*e5436536SAndroid Build Coastguard Worker       /* bitreservoir  =
600*e5436536SAndroid Build Coastguard Worker        * (maxBitRes-minBitRes)/(maxBitRate-minBitrate)*(bitRate-minBitrate)+minBitRes;
601*e5436536SAndroid Build Coastguard Worker        */
602*e5436536SAndroid Build Coastguard Worker       FIXP_DBL slope = fDivNorm(
603*e5436536SAndroid Build Coastguard Worker           (brPerChannel - BITRATE_MIN_LD),
604*e5436536SAndroid Build Coastguard Worker           BITRATE_MAX_LD - BITRATE_MIN_LD); /* calc slope for interpolation */
605*e5436536SAndroid Build Coastguard Worker       bitreservoir = fMultI(slope, (INT)(BITRES_MAX_LD - BITRES_MIN_LD)) +
606*e5436536SAndroid Build Coastguard Worker                      BITRES_MIN_LD;     /* interpolate */
607*e5436536SAndroid Build Coastguard Worker       bitreservoir = bitreservoir & ~7; /* align to bytes */
608*e5436536SAndroid Build Coastguard Worker     }
609*e5436536SAndroid Build Coastguard Worker 
610*e5436536SAndroid Build Coastguard Worker     int maxBitres;
611*e5436536SAndroid Build Coastguard Worker     qcInit.averageBits = (averageBitsPerFrame + 7) & ~7;
612*e5436536SAndroid Build Coastguard Worker     maxBitres =
613*e5436536SAndroid Build Coastguard Worker         (MIN_BUFSIZE_PER_EFF_CHAN * cm->nChannelsEff) - qcInit.averageBits;
614*e5436536SAndroid Build Coastguard Worker     qcInit.bitRes =
615*e5436536SAndroid Build Coastguard Worker         (bitreservoir != -1) ? fMin(bitreservoir, maxBitres) : maxBitres;
616*e5436536SAndroid Build Coastguard Worker 
617*e5436536SAndroid Build Coastguard Worker     qcInit.maxBits = fixMin(MIN_BUFSIZE_PER_EFF_CHAN * cm->nChannelsEff,
618*e5436536SAndroid Build Coastguard Worker                             ((averageBitsPerFrame + 7) & ~7) + qcInit.bitRes);
619*e5436536SAndroid Build Coastguard Worker     qcInit.maxBits = (config->maxBitsPerFrame != -1)
620*e5436536SAndroid Build Coastguard Worker                          ? fixMin(qcInit.maxBits, config->maxBitsPerFrame)
621*e5436536SAndroid Build Coastguard Worker                          : qcInit.maxBits;
622*e5436536SAndroid Build Coastguard Worker     qcInit.maxBits =
623*e5436536SAndroid Build Coastguard Worker         fixMin(MIN_BUFSIZE_PER_EFF_CHAN * cm->nChannelsEff,
624*e5436536SAndroid Build Coastguard Worker                fixMax(qcInit.maxBits, (averageBitsPerFrame + 7 + 8) & ~7));
625*e5436536SAndroid Build Coastguard Worker 
626*e5436536SAndroid Build Coastguard Worker     qcInit.minBits = fixMax(
627*e5436536SAndroid Build Coastguard Worker         0, ((averageBitsPerFrame - 1) & ~7) - qcInit.bitRes -
628*e5436536SAndroid Build Coastguard Worker                transportEnc_GetStaticBits(
629*e5436536SAndroid Build Coastguard Worker                    hTpEnc, ((averageBitsPerFrame + 7) & ~7) + qcInit.bitRes));
630*e5436536SAndroid Build Coastguard Worker     qcInit.minBits = (config->minBitsPerFrame != -1)
631*e5436536SAndroid Build Coastguard Worker                          ? fixMax(qcInit.minBits, config->minBitsPerFrame)
632*e5436536SAndroid Build Coastguard Worker                          : qcInit.minBits;
633*e5436536SAndroid Build Coastguard Worker     qcInit.minBits = fixMin(
634*e5436536SAndroid Build Coastguard Worker         qcInit.minBits, (averageBitsPerFrame -
635*e5436536SAndroid Build Coastguard Worker                          transportEnc_GetStaticBits(hTpEnc, qcInit.maxBits)) &
636*e5436536SAndroid Build Coastguard Worker                             ~7);
637*e5436536SAndroid Build Coastguard Worker   }
638*e5436536SAndroid Build Coastguard Worker 
639*e5436536SAndroid Build Coastguard Worker   qcInit.sampleRate = config->sampleRate;
640*e5436536SAndroid Build Coastguard Worker   qcInit.isLowDelay = isLowDelay(config->audioObjectType) ? 1 : 0;
641*e5436536SAndroid Build Coastguard Worker   qcInit.nSubFrames = config->nSubFrames;
642*e5436536SAndroid Build Coastguard Worker   qcInit.padding.paddingRest = config->sampleRate;
643*e5436536SAndroid Build Coastguard Worker 
644*e5436536SAndroid Build Coastguard Worker   if (qcInit.maxBits - qcInit.averageBits >=
645*e5436536SAndroid Build Coastguard Worker       ((qcInit.isLowDelay) ? BITRES_MIN_LD : BITRES_MIN) * config->nChannels) {
646*e5436536SAndroid Build Coastguard Worker     qcInit.bitResMode = AACENC_BR_MODE_FULL; /* full bitreservoir */
647*e5436536SAndroid Build Coastguard Worker   } else if (qcInit.maxBits > qcInit.averageBits) {
648*e5436536SAndroid Build Coastguard Worker     qcInit.bitResMode = AACENC_BR_MODE_REDUCED; /* reduced bitreservoir */
649*e5436536SAndroid Build Coastguard Worker   } else {
650*e5436536SAndroid Build Coastguard Worker     qcInit.bitResMode = AACENC_BR_MODE_DISABLED; /* disabled bitreservoir */
651*e5436536SAndroid Build Coastguard Worker   }
652*e5436536SAndroid Build Coastguard Worker 
653*e5436536SAndroid Build Coastguard Worker   /* Configure bitrate distribution strategy. */
654*e5436536SAndroid Build Coastguard Worker   switch (config->channelMode) {
655*e5436536SAndroid Build Coastguard Worker     case MODE_1_2:
656*e5436536SAndroid Build Coastguard Worker     case MODE_1_2_1:
657*e5436536SAndroid Build Coastguard Worker     case MODE_1_2_2:
658*e5436536SAndroid Build Coastguard Worker     case MODE_1_2_2_1:
659*e5436536SAndroid Build Coastguard Worker     case MODE_6_1:
660*e5436536SAndroid Build Coastguard Worker     case MODE_1_2_2_2_1:
661*e5436536SAndroid Build Coastguard Worker     case MODE_7_1_BACK:
662*e5436536SAndroid Build Coastguard Worker     case MODE_7_1_TOP_FRONT:
663*e5436536SAndroid Build Coastguard Worker     case MODE_7_1_REAR_SURROUND:
664*e5436536SAndroid Build Coastguard Worker     case MODE_7_1_FRONT_CENTER:
665*e5436536SAndroid Build Coastguard Worker       qcInit.bitDistributionMode = 0; /* over all elements bitrate estimation */
666*e5436536SAndroid Build Coastguard Worker       break;
667*e5436536SAndroid Build Coastguard Worker     case MODE_1:
668*e5436536SAndroid Build Coastguard Worker     case MODE_2:
669*e5436536SAndroid Build Coastguard Worker     default:                          /* all non mpeg defined channel modes */
670*e5436536SAndroid Build Coastguard Worker       qcInit.bitDistributionMode = 1; /* element-wise bit bitrate estimation */
671*e5436536SAndroid Build Coastguard Worker   }                                   /* config->channelMode */
672*e5436536SAndroid Build Coastguard Worker 
673*e5436536SAndroid Build Coastguard Worker   /* Calc meanPe: qcInit.meanPe = 10.0f * FRAME_LEN_LONG *
674*e5436536SAndroid Build Coastguard Worker    * hAacEnc->bandwidth90dB/(config->sampleRate/2.0f); */
675*e5436536SAndroid Build Coastguard Worker   bw_ratio =
676*e5436536SAndroid Build Coastguard Worker       fDivNorm((FIXP_DBL)(10 * config->framelength * hAacEnc->bandwidth90dB),
677*e5436536SAndroid Build Coastguard Worker                (FIXP_DBL)(config->sampleRate), &qbw);
678*e5436536SAndroid Build Coastguard Worker   qcInit.meanPe =
679*e5436536SAndroid Build Coastguard Worker       fMax((INT)scaleValue(bw_ratio, qbw + 1 - (DFRACT_BITS - 1)), 1);
680*e5436536SAndroid Build Coastguard Worker 
681*e5436536SAndroid Build Coastguard Worker   /* Calc maxBitFac, scale it to 24 bit accuracy */
682*e5436536SAndroid Build Coastguard Worker   mbfac = fDivNorm(qcInit.maxBits, qcInit.averageBits / qcInit.nSubFrames,
683*e5436536SAndroid Build Coastguard Worker                    &mbfac_e);
684*e5436536SAndroid Build Coastguard Worker   qcInit.maxBitFac = scaleValue(mbfac, -(DFRACT_BITS - 1 - 24 - mbfac_e));
685*e5436536SAndroid Build Coastguard Worker 
686*e5436536SAndroid Build Coastguard Worker   switch (config->bitrateMode) {
687*e5436536SAndroid Build Coastguard Worker     case AACENC_BR_MODE_CBR:
688*e5436536SAndroid Build Coastguard Worker       qcInit.bitrateMode = QCDATA_BR_MODE_CBR;
689*e5436536SAndroid Build Coastguard Worker       break;
690*e5436536SAndroid Build Coastguard Worker     case AACENC_BR_MODE_VBR_1:
691*e5436536SAndroid Build Coastguard Worker       qcInit.bitrateMode = QCDATA_BR_MODE_VBR_1;
692*e5436536SAndroid Build Coastguard Worker       break;
693*e5436536SAndroid Build Coastguard Worker     case AACENC_BR_MODE_VBR_2:
694*e5436536SAndroid Build Coastguard Worker       qcInit.bitrateMode = QCDATA_BR_MODE_VBR_2;
695*e5436536SAndroid Build Coastguard Worker       break;
696*e5436536SAndroid Build Coastguard Worker     case AACENC_BR_MODE_VBR_3:
697*e5436536SAndroid Build Coastguard Worker       qcInit.bitrateMode = QCDATA_BR_MODE_VBR_3;
698*e5436536SAndroid Build Coastguard Worker       break;
699*e5436536SAndroid Build Coastguard Worker     case AACENC_BR_MODE_VBR_4:
700*e5436536SAndroid Build Coastguard Worker       qcInit.bitrateMode = QCDATA_BR_MODE_VBR_4;
701*e5436536SAndroid Build Coastguard Worker       break;
702*e5436536SAndroid Build Coastguard Worker     case AACENC_BR_MODE_VBR_5:
703*e5436536SAndroid Build Coastguard Worker       qcInit.bitrateMode = QCDATA_BR_MODE_VBR_5;
704*e5436536SAndroid Build Coastguard Worker       break;
705*e5436536SAndroid Build Coastguard Worker     case AACENC_BR_MODE_SFR:
706*e5436536SAndroid Build Coastguard Worker       qcInit.bitrateMode = QCDATA_BR_MODE_SFR;
707*e5436536SAndroid Build Coastguard Worker       break;
708*e5436536SAndroid Build Coastguard Worker     case AACENC_BR_MODE_FF:
709*e5436536SAndroid Build Coastguard Worker       qcInit.bitrateMode = QCDATA_BR_MODE_FF;
710*e5436536SAndroid Build Coastguard Worker       break;
711*e5436536SAndroid Build Coastguard Worker     default:
712*e5436536SAndroid Build Coastguard Worker       ErrorStatus = AAC_ENC_UNSUPPORTED_BITRATE_MODE;
713*e5436536SAndroid Build Coastguard Worker       goto bail;
714*e5436536SAndroid Build Coastguard Worker   }
715*e5436536SAndroid Build Coastguard Worker 
716*e5436536SAndroid Build Coastguard Worker   qcInit.invQuant = (config->useRequant) ? 2 : 0;
717*e5436536SAndroid Build Coastguard Worker 
718*e5436536SAndroid Build Coastguard Worker   /* maxIterations should be set to the maximum number of requantization
719*e5436536SAndroid Build Coastguard Worker    * iterations that are allowed before the crash recovery functionality is
720*e5436536SAndroid Build Coastguard Worker    * activated. This setting should be adjusted to the processing power
721*e5436536SAndroid Build Coastguard Worker    * available, i.e. to the processing power headroom in one frame that is still
722*e5436536SAndroid Build Coastguard Worker    * left after normal encoding without requantization. Please note that if
723*e5436536SAndroid Build Coastguard Worker    * activated this functionality is used most likely only in cases where the
724*e5436536SAndroid Build Coastguard Worker    * encoder is operating beyond recommended settings, i.e. the audio quality is
725*e5436536SAndroid Build Coastguard Worker    * suboptimal anyway. Activating the crash recovery does not further reduce
726*e5436536SAndroid Build Coastguard Worker    * audio quality significantly in these cases. */
727*e5436536SAndroid Build Coastguard Worker   if (isLowDelay(config->audioObjectType)) {
728*e5436536SAndroid Build Coastguard Worker     qcInit.maxIterations = 2;
729*e5436536SAndroid Build Coastguard Worker   } else {
730*e5436536SAndroid Build Coastguard Worker     qcInit.maxIterations = 5;
731*e5436536SAndroid Build Coastguard Worker   }
732*e5436536SAndroid Build Coastguard Worker 
733*e5436536SAndroid Build Coastguard Worker   qcInit.bitrate = config->bitRate - config->ancDataBitRate;
734*e5436536SAndroid Build Coastguard Worker 
735*e5436536SAndroid Build Coastguard Worker   qcInit.staticBits = transportEnc_GetStaticBits(
736*e5436536SAndroid Build Coastguard Worker       hTpEnc, qcInit.averageBits / qcInit.nSubFrames);
737*e5436536SAndroid Build Coastguard Worker 
738*e5436536SAndroid Build Coastguard Worker   ErrorStatus = FDKaacEnc_QCInit(hAacEnc->qcKernel, &qcInit, initFlags);
739*e5436536SAndroid Build Coastguard Worker   if (ErrorStatus != AAC_ENC_OK) goto bail;
740*e5436536SAndroid Build Coastguard Worker 
741*e5436536SAndroid Build Coastguard Worker   /* Map virtual aot's to intern aot used in bitstream writer. */
742*e5436536SAndroid Build Coastguard Worker   switch (hAacEnc->config->audioObjectType) {
743*e5436536SAndroid Build Coastguard Worker     case AOT_MP2_AAC_LC:
744*e5436536SAndroid Build Coastguard Worker       hAacEnc->aot = AOT_AAC_LC;
745*e5436536SAndroid Build Coastguard Worker       break;
746*e5436536SAndroid Build Coastguard Worker     case AOT_MP2_SBR:
747*e5436536SAndroid Build Coastguard Worker       hAacEnc->aot = AOT_SBR;
748*e5436536SAndroid Build Coastguard Worker       break;
749*e5436536SAndroid Build Coastguard Worker     default:
750*e5436536SAndroid Build Coastguard Worker       hAacEnc->aot = hAacEnc->config->audioObjectType;
751*e5436536SAndroid Build Coastguard Worker   }
752*e5436536SAndroid Build Coastguard Worker 
753*e5436536SAndroid Build Coastguard Worker   /* common things */
754*e5436536SAndroid Build Coastguard Worker 
755*e5436536SAndroid Build Coastguard Worker   return AAC_ENC_OK;
756*e5436536SAndroid Build Coastguard Worker 
757*e5436536SAndroid Build Coastguard Worker bail:
758*e5436536SAndroid Build Coastguard Worker 
759*e5436536SAndroid Build Coastguard Worker   return ErrorStatus;
760*e5436536SAndroid Build Coastguard Worker }
761*e5436536SAndroid Build Coastguard Worker 
762*e5436536SAndroid Build Coastguard Worker /*---------------------------------------------------------------------------
763*e5436536SAndroid Build Coastguard Worker 
764*e5436536SAndroid Build Coastguard Worker     functionname: FDKaacEnc_EncodeFrame
765*e5436536SAndroid Build Coastguard Worker     description:  encodes one frame
766*e5436536SAndroid Build Coastguard Worker     returns:      error code
767*e5436536SAndroid Build Coastguard Worker 
768*e5436536SAndroid Build Coastguard Worker   ---------------------------------------------------------------------------*/
FDKaacEnc_EncodeFrame(HANDLE_AAC_ENC hAacEnc,HANDLE_TRANSPORTENC hTpEnc,INT_PCM * RESTRICT inputBuffer,const UINT inputBufferBufSize,INT * nOutBytes,AACENC_EXT_PAYLOAD extPayload[MAX_TOTAL_EXT_PAYLOADS])769*e5436536SAndroid Build Coastguard Worker AAC_ENCODER_ERROR FDKaacEnc_EncodeFrame(
770*e5436536SAndroid Build Coastguard Worker     HANDLE_AAC_ENC hAacEnc, /* encoder handle */
771*e5436536SAndroid Build Coastguard Worker     HANDLE_TRANSPORTENC hTpEnc, INT_PCM *RESTRICT inputBuffer,
772*e5436536SAndroid Build Coastguard Worker     const UINT inputBufferBufSize, INT *nOutBytes,
773*e5436536SAndroid Build Coastguard Worker     AACENC_EXT_PAYLOAD extPayload[MAX_TOTAL_EXT_PAYLOADS]) {
774*e5436536SAndroid Build Coastguard Worker   AAC_ENCODER_ERROR ErrorStatus;
775*e5436536SAndroid Build Coastguard Worker   int el, n, c = 0;
776*e5436536SAndroid Build Coastguard Worker   UCHAR extPayloadUsed[MAX_TOTAL_EXT_PAYLOADS];
777*e5436536SAndroid Build Coastguard Worker 
778*e5436536SAndroid Build Coastguard Worker   CHANNEL_MAPPING *cm = &hAacEnc->channelMapping;
779*e5436536SAndroid Build Coastguard Worker 
780*e5436536SAndroid Build Coastguard Worker   PSY_OUT *psyOut = hAacEnc->psyOut[c];
781*e5436536SAndroid Build Coastguard Worker   QC_OUT *qcOut = hAacEnc->qcOut[c];
782*e5436536SAndroid Build Coastguard Worker 
783*e5436536SAndroid Build Coastguard Worker   FDKmemclear(extPayloadUsed, MAX_TOTAL_EXT_PAYLOADS * sizeof(UCHAR));
784*e5436536SAndroid Build Coastguard Worker 
785*e5436536SAndroid Build Coastguard Worker   qcOut->elementExtBits = 0; /* sum up all extended bit of each element */
786*e5436536SAndroid Build Coastguard Worker   qcOut->staticBits = 0;     /* sum up side info bits of each element */
787*e5436536SAndroid Build Coastguard Worker   qcOut->totalNoRedPe = 0;   /* sum up PE */
788*e5436536SAndroid Build Coastguard Worker 
789*e5436536SAndroid Build Coastguard Worker   /* advance psychoacoustics */
790*e5436536SAndroid Build Coastguard Worker   for (el = 0; el < cm->nElements; el++) {
791*e5436536SAndroid Build Coastguard Worker     ELEMENT_INFO elInfo = cm->elInfo[el];
792*e5436536SAndroid Build Coastguard Worker 
793*e5436536SAndroid Build Coastguard Worker     if ((elInfo.elType == ID_SCE) || (elInfo.elType == ID_CPE) ||
794*e5436536SAndroid Build Coastguard Worker         (elInfo.elType == ID_LFE)) {
795*e5436536SAndroid Build Coastguard Worker       int ch;
796*e5436536SAndroid Build Coastguard Worker 
797*e5436536SAndroid Build Coastguard Worker       /* update pointer!*/
798*e5436536SAndroid Build Coastguard Worker       for (ch = 0; ch < elInfo.nChannelsInEl; ch++) {
799*e5436536SAndroid Build Coastguard Worker         PSY_OUT_CHANNEL *psyOutChan =
800*e5436536SAndroid Build Coastguard Worker             psyOut->psyOutElement[el]->psyOutChannel[ch];
801*e5436536SAndroid Build Coastguard Worker         QC_OUT_CHANNEL *qcOutChan = qcOut->qcElement[el]->qcOutChannel[ch];
802*e5436536SAndroid Build Coastguard Worker 
803*e5436536SAndroid Build Coastguard Worker         psyOutChan->mdctSpectrum = qcOutChan->mdctSpectrum;
804*e5436536SAndroid Build Coastguard Worker         psyOutChan->sfbSpreadEnergy = qcOutChan->sfbSpreadEnergy;
805*e5436536SAndroid Build Coastguard Worker         psyOutChan->sfbEnergy = qcOutChan->sfbEnergy;
806*e5436536SAndroid Build Coastguard Worker         psyOutChan->sfbEnergyLdData = qcOutChan->sfbEnergyLdData;
807*e5436536SAndroid Build Coastguard Worker         psyOutChan->sfbMinSnrLdData = qcOutChan->sfbMinSnrLdData;
808*e5436536SAndroid Build Coastguard Worker         psyOutChan->sfbThresholdLdData = qcOutChan->sfbThresholdLdData;
809*e5436536SAndroid Build Coastguard Worker       }
810*e5436536SAndroid Build Coastguard Worker 
811*e5436536SAndroid Build Coastguard Worker       ErrorStatus = FDKaacEnc_psyMain(
812*e5436536SAndroid Build Coastguard Worker           elInfo.nChannelsInEl, hAacEnc->psyKernel->psyElement[el],
813*e5436536SAndroid Build Coastguard Worker           hAacEnc->psyKernel->psyDynamic, hAacEnc->psyKernel->psyConf,
814*e5436536SAndroid Build Coastguard Worker           psyOut->psyOutElement[el], inputBuffer, inputBufferBufSize,
815*e5436536SAndroid Build Coastguard Worker           cm->elInfo[el].ChannelIndex, cm->nChannels);
816*e5436536SAndroid Build Coastguard Worker 
817*e5436536SAndroid Build Coastguard Worker       if (ErrorStatus != AAC_ENC_OK) return ErrorStatus;
818*e5436536SAndroid Build Coastguard Worker 
819*e5436536SAndroid Build Coastguard Worker       /* FormFactor, Pe and staticBitDemand calculation */
820*e5436536SAndroid Build Coastguard Worker       ErrorStatus = FDKaacEnc_QCMainPrepare(
821*e5436536SAndroid Build Coastguard Worker           &elInfo, hAacEnc->qcKernel->hAdjThr->adjThrStateElem[el],
822*e5436536SAndroid Build Coastguard Worker           psyOut->psyOutElement[el], qcOut->qcElement[el], hAacEnc->aot,
823*e5436536SAndroid Build Coastguard Worker           hAacEnc->config->syntaxFlags, hAacEnc->config->epConfig);
824*e5436536SAndroid Build Coastguard Worker 
825*e5436536SAndroid Build Coastguard Worker       if (ErrorStatus != AAC_ENC_OK) return ErrorStatus;
826*e5436536SAndroid Build Coastguard Worker 
827*e5436536SAndroid Build Coastguard Worker       /*-------------------------------------------- */
828*e5436536SAndroid Build Coastguard Worker 
829*e5436536SAndroid Build Coastguard Worker       qcOut->qcElement[el]->extBitsUsed = 0;
830*e5436536SAndroid Build Coastguard Worker       qcOut->qcElement[el]->nExtensions = 0;
831*e5436536SAndroid Build Coastguard Worker       /* reset extension payload */
832*e5436536SAndroid Build Coastguard Worker       FDKmemclear(&qcOut->qcElement[el]->extension,
833*e5436536SAndroid Build Coastguard Worker                   (1) * sizeof(QC_OUT_EXTENSION));
834*e5436536SAndroid Build Coastguard Worker 
835*e5436536SAndroid Build Coastguard Worker       for (n = 0; n < MAX_TOTAL_EXT_PAYLOADS; n++) {
836*e5436536SAndroid Build Coastguard Worker         if (!extPayloadUsed[n] && (extPayload[n].associatedChElement == el) &&
837*e5436536SAndroid Build Coastguard Worker             (extPayload[n].dataSize > 0) && (extPayload[n].pData != NULL)) {
838*e5436536SAndroid Build Coastguard Worker           int idx = qcOut->qcElement[el]->nExtensions++;
839*e5436536SAndroid Build Coastguard Worker 
840*e5436536SAndroid Build Coastguard Worker           qcOut->qcElement[el]->extension[idx].type =
841*e5436536SAndroid Build Coastguard Worker               extPayload[n].dataType; /* Perform a sanity check on the type? */
842*e5436536SAndroid Build Coastguard Worker           qcOut->qcElement[el]->extension[idx].nPayloadBits =
843*e5436536SAndroid Build Coastguard Worker               extPayload[n].dataSize;
844*e5436536SAndroid Build Coastguard Worker           qcOut->qcElement[el]->extension[idx].pPayload = extPayload[n].pData;
845*e5436536SAndroid Build Coastguard Worker           /* Now ask the bitstream encoder how many bits we need to encode the
846*e5436536SAndroid Build Coastguard Worker            * data with the current bitstream syntax: */
847*e5436536SAndroid Build Coastguard Worker           qcOut->qcElement[el]->extBitsUsed += FDKaacEnc_writeExtensionData(
848*e5436536SAndroid Build Coastguard Worker               NULL, &qcOut->qcElement[el]->extension[idx], 0, 0,
849*e5436536SAndroid Build Coastguard Worker               hAacEnc->config->syntaxFlags, hAacEnc->aot,
850*e5436536SAndroid Build Coastguard Worker               hAacEnc->config->epConfig);
851*e5436536SAndroid Build Coastguard Worker           extPayloadUsed[n] = 1;
852*e5436536SAndroid Build Coastguard Worker         }
853*e5436536SAndroid Build Coastguard Worker       }
854*e5436536SAndroid Build Coastguard Worker 
855*e5436536SAndroid Build Coastguard Worker       /* sum up extension and static bits for all channel elements */
856*e5436536SAndroid Build Coastguard Worker       qcOut->elementExtBits += qcOut->qcElement[el]->extBitsUsed;
857*e5436536SAndroid Build Coastguard Worker       qcOut->staticBits += qcOut->qcElement[el]->staticBitsUsed;
858*e5436536SAndroid Build Coastguard Worker 
859*e5436536SAndroid Build Coastguard Worker       /* sum up pe */
860*e5436536SAndroid Build Coastguard Worker       qcOut->totalNoRedPe += qcOut->qcElement[el]->peData.pe;
861*e5436536SAndroid Build Coastguard Worker     }
862*e5436536SAndroid Build Coastguard Worker   }
863*e5436536SAndroid Build Coastguard Worker 
864*e5436536SAndroid Build Coastguard Worker   qcOut->nExtensions = 0;
865*e5436536SAndroid Build Coastguard Worker   qcOut->globalExtBits = 0;
866*e5436536SAndroid Build Coastguard Worker 
867*e5436536SAndroid Build Coastguard Worker   /* reset extension payload */
868*e5436536SAndroid Build Coastguard Worker   FDKmemclear(&qcOut->extension, (2 + 2) * sizeof(QC_OUT_EXTENSION));
869*e5436536SAndroid Build Coastguard Worker 
870*e5436536SAndroid Build Coastguard Worker   /* Add extension payload not assigned to an channel element
871*e5436536SAndroid Build Coastguard Worker     (Ancillary data is the only supported type up to now) */
872*e5436536SAndroid Build Coastguard Worker   for (n = 0; n < MAX_TOTAL_EXT_PAYLOADS; n++) {
873*e5436536SAndroid Build Coastguard Worker     if (!extPayloadUsed[n] && (extPayload[n].associatedChElement == -1) &&
874*e5436536SAndroid Build Coastguard Worker         (extPayload[n].pData != NULL)) {
875*e5436536SAndroid Build Coastguard Worker       UINT payloadBits = 0;
876*e5436536SAndroid Build Coastguard Worker 
877*e5436536SAndroid Build Coastguard Worker       if (extPayload[n].dataType == EXT_DATA_ELEMENT) {
878*e5436536SAndroid Build Coastguard Worker         if (hAacEnc->ancillaryBitsPerFrame) {
879*e5436536SAndroid Build Coastguard Worker           /* granted frame dse bitrate */
880*e5436536SAndroid Build Coastguard Worker           payloadBits = hAacEnc->ancillaryBitsPerFrame;
881*e5436536SAndroid Build Coastguard Worker         } else {
882*e5436536SAndroid Build Coastguard Worker           /* write anc data if bitrate constraint fulfilled */
883*e5436536SAndroid Build Coastguard Worker           if ((extPayload[n].dataSize >> 3) <=
884*e5436536SAndroid Build Coastguard Worker               hAacEnc->config->maxAncBytesPerAU) {
885*e5436536SAndroid Build Coastguard Worker             payloadBits = extPayload[n].dataSize;
886*e5436536SAndroid Build Coastguard Worker           }
887*e5436536SAndroid Build Coastguard Worker         }
888*e5436536SAndroid Build Coastguard Worker         payloadBits = fixMin(extPayload[n].dataSize, payloadBits);
889*e5436536SAndroid Build Coastguard Worker       } else {
890*e5436536SAndroid Build Coastguard Worker         payloadBits = extPayload[n].dataSize;
891*e5436536SAndroid Build Coastguard Worker       }
892*e5436536SAndroid Build Coastguard Worker 
893*e5436536SAndroid Build Coastguard Worker       if (payloadBits > 0) {
894*e5436536SAndroid Build Coastguard Worker         int idx = qcOut->nExtensions++;
895*e5436536SAndroid Build Coastguard Worker 
896*e5436536SAndroid Build Coastguard Worker         qcOut->extension[idx].type =
897*e5436536SAndroid Build Coastguard Worker             extPayload[n].dataType; /* Perform a sanity check on the type? */
898*e5436536SAndroid Build Coastguard Worker         qcOut->extension[idx].nPayloadBits = payloadBits;
899*e5436536SAndroid Build Coastguard Worker         qcOut->extension[idx].pPayload = extPayload[n].pData;
900*e5436536SAndroid Build Coastguard Worker         /* Now ask the bitstream encoder how many bits we need to encode the
901*e5436536SAndroid Build Coastguard Worker          * data with the current bitstream syntax: */
902*e5436536SAndroid Build Coastguard Worker         qcOut->globalExtBits += FDKaacEnc_writeExtensionData(
903*e5436536SAndroid Build Coastguard Worker             NULL, &qcOut->extension[idx], 0, 0, hAacEnc->config->syntaxFlags,
904*e5436536SAndroid Build Coastguard Worker             hAacEnc->aot, hAacEnc->config->epConfig);
905*e5436536SAndroid Build Coastguard Worker         if (extPayload[n].dataType == EXT_DATA_ELEMENT) {
906*e5436536SAndroid Build Coastguard Worker           /* substract the processed bits */
907*e5436536SAndroid Build Coastguard Worker           extPayload[n].dataSize -= payloadBits;
908*e5436536SAndroid Build Coastguard Worker         }
909*e5436536SAndroid Build Coastguard Worker         extPayloadUsed[n] = 1;
910*e5436536SAndroid Build Coastguard Worker       }
911*e5436536SAndroid Build Coastguard Worker     }
912*e5436536SAndroid Build Coastguard Worker   }
913*e5436536SAndroid Build Coastguard Worker 
914*e5436536SAndroid Build Coastguard Worker   if (!(hAacEnc->config->syntaxFlags & (AC_SCALABLE | AC_ER))) {
915*e5436536SAndroid Build Coastguard Worker     qcOut->globalExtBits += EL_ID_BITS; /* add bits for ID_END */
916*e5436536SAndroid Build Coastguard Worker   }
917*e5436536SAndroid Build Coastguard Worker 
918*e5436536SAndroid Build Coastguard Worker   /* build bitstream all nSubFrames */
919*e5436536SAndroid Build Coastguard Worker   {
920*e5436536SAndroid Build Coastguard Worker     INT totalBits = 0; /* Total AU bits */
921*e5436536SAndroid Build Coastguard Worker     ;
922*e5436536SAndroid Build Coastguard Worker     INT avgTotalBits = 0;
923*e5436536SAndroid Build Coastguard Worker 
924*e5436536SAndroid Build Coastguard Worker     /*-------------------------------------------- */
925*e5436536SAndroid Build Coastguard Worker     /* Get average total bits */
926*e5436536SAndroid Build Coastguard Worker     /*-------------------------------------------- */
927*e5436536SAndroid Build Coastguard Worker     {
928*e5436536SAndroid Build Coastguard Worker       /* frame wise bitrate adaption */
929*e5436536SAndroid Build Coastguard Worker       FDKaacEnc_AdjustBitrate(
930*e5436536SAndroid Build Coastguard Worker           hAacEnc->qcKernel, cm, &avgTotalBits, hAacEnc->config->bitRate,
931*e5436536SAndroid Build Coastguard Worker           hAacEnc->config->sampleRate, hAacEnc->config->framelength);
932*e5436536SAndroid Build Coastguard Worker 
933*e5436536SAndroid Build Coastguard Worker       /* adjust super frame bitrate */
934*e5436536SAndroid Build Coastguard Worker       avgTotalBits *= hAacEnc->config->nSubFrames;
935*e5436536SAndroid Build Coastguard Worker     }
936*e5436536SAndroid Build Coastguard Worker 
937*e5436536SAndroid Build Coastguard Worker     /* Make first estimate of transport header overhead.
938*e5436536SAndroid Build Coastguard Worker        Take maximum possible frame size into account to prevent bitreservoir
939*e5436536SAndroid Build Coastguard Worker        underrun. */
940*e5436536SAndroid Build Coastguard Worker     hAacEnc->qcKernel->globHdrBits = transportEnc_GetStaticBits(
941*e5436536SAndroid Build Coastguard Worker         hTpEnc, avgTotalBits + hAacEnc->qcKernel->bitResTot);
942*e5436536SAndroid Build Coastguard Worker 
943*e5436536SAndroid Build Coastguard Worker     /*-------------------------------------------- */
944*e5436536SAndroid Build Coastguard Worker     /*-------------------------------------------- */
945*e5436536SAndroid Build Coastguard Worker     /*-------------------------------------------- */
946*e5436536SAndroid Build Coastguard Worker 
947*e5436536SAndroid Build Coastguard Worker     ErrorStatus = FDKaacEnc_QCMain(
948*e5436536SAndroid Build Coastguard Worker         hAacEnc->qcKernel, hAacEnc->psyOut, hAacEnc->qcOut, avgTotalBits, cm,
949*e5436536SAndroid Build Coastguard Worker         hAacEnc->aot, hAacEnc->config->syntaxFlags, hAacEnc->config->epConfig);
950*e5436536SAndroid Build Coastguard Worker 
951*e5436536SAndroid Build Coastguard Worker     if (ErrorStatus != AAC_ENC_OK) return ErrorStatus;
952*e5436536SAndroid Build Coastguard Worker     /*-------------------------------------------- */
953*e5436536SAndroid Build Coastguard Worker 
954*e5436536SAndroid Build Coastguard Worker     /*-------------------------------------------- */
955*e5436536SAndroid Build Coastguard Worker     ErrorStatus = FDKaacEnc_updateFillBits(
956*e5436536SAndroid Build Coastguard Worker         cm, hAacEnc->qcKernel, hAacEnc->qcKernel->elementBits, hAacEnc->qcOut);
957*e5436536SAndroid Build Coastguard Worker     if (ErrorStatus != AAC_ENC_OK) return ErrorStatus;
958*e5436536SAndroid Build Coastguard Worker 
959*e5436536SAndroid Build Coastguard Worker     /*-------------------------------------------- */
960*e5436536SAndroid Build Coastguard Worker     ErrorStatus = FDKaacEnc_FinalizeBitConsumption(
961*e5436536SAndroid Build Coastguard Worker         cm, hAacEnc->qcKernel, qcOut, qcOut->qcElement, hTpEnc, hAacEnc->aot,
962*e5436536SAndroid Build Coastguard Worker         hAacEnc->config->syntaxFlags, hAacEnc->config->epConfig);
963*e5436536SAndroid Build Coastguard Worker     if (ErrorStatus != AAC_ENC_OK) return ErrorStatus;
964*e5436536SAndroid Build Coastguard Worker     /*-------------------------------------------- */
965*e5436536SAndroid Build Coastguard Worker     totalBits += qcOut->totalBits;
966*e5436536SAndroid Build Coastguard Worker 
967*e5436536SAndroid Build Coastguard Worker     /*-------------------------------------------- */
968*e5436536SAndroid Build Coastguard Worker     FDKaacEnc_updateBitres(cm, hAacEnc->qcKernel, hAacEnc->qcOut);
969*e5436536SAndroid Build Coastguard Worker 
970*e5436536SAndroid Build Coastguard Worker     /*-------------------------------------------- */
971*e5436536SAndroid Build Coastguard Worker 
972*e5436536SAndroid Build Coastguard Worker     /* for ( all sub frames ) ... */
973*e5436536SAndroid Build Coastguard Worker     /* write bitstream header */
974*e5436536SAndroid Build Coastguard Worker     if (TRANSPORTENC_OK !=
975*e5436536SAndroid Build Coastguard Worker         transportEnc_WriteAccessUnit(hTpEnc, totalBits,
976*e5436536SAndroid Build Coastguard Worker                                      FDKaacEnc_EncBitresToTpBitres(hAacEnc),
977*e5436536SAndroid Build Coastguard Worker                                      cm->nChannelsEff)) {
978*e5436536SAndroid Build Coastguard Worker       return AAC_ENC_UNKNOWN;
979*e5436536SAndroid Build Coastguard Worker     }
980*e5436536SAndroid Build Coastguard Worker 
981*e5436536SAndroid Build Coastguard Worker     /* write bitstream */
982*e5436536SAndroid Build Coastguard Worker     ErrorStatus = FDKaacEnc_WriteBitstream(
983*e5436536SAndroid Build Coastguard Worker         hTpEnc, cm, qcOut, psyOut, hAacEnc->qcKernel, hAacEnc->aot,
984*e5436536SAndroid Build Coastguard Worker         hAacEnc->config->syntaxFlags, hAacEnc->config->epConfig);
985*e5436536SAndroid Build Coastguard Worker 
986*e5436536SAndroid Build Coastguard Worker     if (ErrorStatus != AAC_ENC_OK) return ErrorStatus;
987*e5436536SAndroid Build Coastguard Worker 
988*e5436536SAndroid Build Coastguard Worker     /* transportEnc_EndAccessUnit() is being called inside
989*e5436536SAndroid Build Coastguard Worker      * FDKaacEnc_WriteBitstream() */
990*e5436536SAndroid Build Coastguard Worker     if (TRANSPORTENC_OK != transportEnc_GetFrame(hTpEnc, nOutBytes)) {
991*e5436536SAndroid Build Coastguard Worker       return AAC_ENC_UNKNOWN;
992*e5436536SAndroid Build Coastguard Worker     }
993*e5436536SAndroid Build Coastguard Worker 
994*e5436536SAndroid Build Coastguard Worker   } /* -end- if (curFrame==hAacEnc->qcKernel->nSubFrames) */
995*e5436536SAndroid Build Coastguard Worker 
996*e5436536SAndroid Build Coastguard Worker   /*-------------------------------------------- */
997*e5436536SAndroid Build Coastguard Worker   return AAC_ENC_OK;
998*e5436536SAndroid Build Coastguard Worker }
999*e5436536SAndroid Build Coastguard Worker 
1000*e5436536SAndroid Build Coastguard Worker /*---------------------------------------------------------------------------
1001*e5436536SAndroid Build Coastguard Worker 
1002*e5436536SAndroid Build Coastguard Worker     functionname:FDKaacEnc_Close
1003*e5436536SAndroid Build Coastguard Worker     description: delete encoder instance
1004*e5436536SAndroid Build Coastguard Worker     returns:
1005*e5436536SAndroid Build Coastguard Worker 
1006*e5436536SAndroid Build Coastguard Worker   ---------------------------------------------------------------------------*/
1007*e5436536SAndroid Build Coastguard Worker 
FDKaacEnc_Close(HANDLE_AAC_ENC * phAacEnc)1008*e5436536SAndroid Build Coastguard Worker void FDKaacEnc_Close(HANDLE_AAC_ENC *phAacEnc) /* encoder handle */
1009*e5436536SAndroid Build Coastguard Worker {
1010*e5436536SAndroid Build Coastguard Worker   if (*phAacEnc == NULL) {
1011*e5436536SAndroid Build Coastguard Worker     return;
1012*e5436536SAndroid Build Coastguard Worker   }
1013*e5436536SAndroid Build Coastguard Worker   AAC_ENC *hAacEnc = (AAC_ENC *)*phAacEnc;
1014*e5436536SAndroid Build Coastguard Worker 
1015*e5436536SAndroid Build Coastguard Worker   if (hAacEnc->dynamic_RAM != NULL) FreeAACdynamic_RAM(&hAacEnc->dynamic_RAM);
1016*e5436536SAndroid Build Coastguard Worker 
1017*e5436536SAndroid Build Coastguard Worker   FDKaacEnc_PsyClose(&hAacEnc->psyKernel, hAacEnc->psyOut);
1018*e5436536SAndroid Build Coastguard Worker 
1019*e5436536SAndroid Build Coastguard Worker   FDKaacEnc_QCClose(&hAacEnc->qcKernel, hAacEnc->qcOut);
1020*e5436536SAndroid Build Coastguard Worker 
1021*e5436536SAndroid Build Coastguard Worker   FreeRam_aacEnc_AacEncoder(phAacEnc);
1022*e5436536SAndroid Build Coastguard Worker }
1023*e5436536SAndroid Build Coastguard Worker 
1024*e5436536SAndroid Build Coastguard Worker /* The following functions are in this source file only for convenience and */
1025*e5436536SAndroid Build Coastguard Worker /* need not be visible outside of a possible encoder library. */
1026*e5436536SAndroid Build Coastguard Worker 
1027*e5436536SAndroid Build Coastguard Worker /* basic defines for ancillary data */
1028*e5436536SAndroid Build Coastguard Worker #define MAX_ANCRATE 19200 /* ancillary rate >= 19200 isn't valid */
1029*e5436536SAndroid Build Coastguard Worker 
1030*e5436536SAndroid Build Coastguard Worker /*---------------------------------------------------------------------------
1031*e5436536SAndroid Build Coastguard Worker 
1032*e5436536SAndroid Build Coastguard Worker     functionname:  FDKaacEnc_InitCheckAncillary
1033*e5436536SAndroid Build Coastguard Worker     description:   initialize and check ancillary data struct
1034*e5436536SAndroid Build Coastguard Worker     return:        if success or NULL if error
1035*e5436536SAndroid Build Coastguard Worker 
1036*e5436536SAndroid Build Coastguard Worker   ---------------------------------------------------------------------------*/
FDKaacEnc_InitCheckAncillary(INT bitRate,INT framelength,INT ancillaryRate,INT * ancillaryBitsPerFrame,INT sampleRate)1037*e5436536SAndroid Build Coastguard Worker static AAC_ENCODER_ERROR FDKaacEnc_InitCheckAncillary(
1038*e5436536SAndroid Build Coastguard Worker     INT bitRate, INT framelength, INT ancillaryRate, INT *ancillaryBitsPerFrame,
1039*e5436536SAndroid Build Coastguard Worker     INT sampleRate) {
1040*e5436536SAndroid Build Coastguard Worker   /* don't use negative ancillary rates */
1041*e5436536SAndroid Build Coastguard Worker   if (ancillaryRate < -1) return AAC_ENC_UNSUPPORTED_ANC_BITRATE;
1042*e5436536SAndroid Build Coastguard Worker 
1043*e5436536SAndroid Build Coastguard Worker   /* check if ancillary rate is ok */
1044*e5436536SAndroid Build Coastguard Worker   if ((ancillaryRate != (-1)) && (ancillaryRate != 0)) {
1045*e5436536SAndroid Build Coastguard Worker     /* ancRate <= 15% of bitrate && ancRate < 19200 */
1046*e5436536SAndroid Build Coastguard Worker     if ((ancillaryRate >= MAX_ANCRATE) ||
1047*e5436536SAndroid Build Coastguard Worker         ((ancillaryRate * 20) > (bitRate * 3))) {
1048*e5436536SAndroid Build Coastguard Worker       return AAC_ENC_UNSUPPORTED_ANC_BITRATE;
1049*e5436536SAndroid Build Coastguard Worker     }
1050*e5436536SAndroid Build Coastguard Worker   } else if (ancillaryRate == -1) {
1051*e5436536SAndroid Build Coastguard Worker     /* if no special ancRate is requested but a ancillary file is
1052*e5436536SAndroid Build Coastguard Worker        stated, then generate a ancillary rate matching to the bitrate */
1053*e5436536SAndroid Build Coastguard Worker     if (bitRate >= (MAX_ANCRATE * 10)) {
1054*e5436536SAndroid Build Coastguard Worker       /* ancillary rate is 19199 */
1055*e5436536SAndroid Build Coastguard Worker       ancillaryRate = (MAX_ANCRATE - 1);
1056*e5436536SAndroid Build Coastguard Worker     } else { /* 10% of bitrate */
1057*e5436536SAndroid Build Coastguard Worker       ancillaryRate = bitRate / 10;
1058*e5436536SAndroid Build Coastguard Worker     }
1059*e5436536SAndroid Build Coastguard Worker   }
1060*e5436536SAndroid Build Coastguard Worker 
1061*e5436536SAndroid Build Coastguard Worker   /* make ancillaryBitsPerFrame byte align */
1062*e5436536SAndroid Build Coastguard Worker   *ancillaryBitsPerFrame =
1063*e5436536SAndroid Build Coastguard Worker       FDKaacEnc_CalcBitsPerFrame(ancillaryRate, framelength, sampleRate) & ~0x7;
1064*e5436536SAndroid Build Coastguard Worker 
1065*e5436536SAndroid Build Coastguard Worker   return AAC_ENC_OK;
1066*e5436536SAndroid Build Coastguard Worker }
1067