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