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