xref: /aosp_15_r20/external/aac/libAACenc/src/aacenc_lib.cpp (revision e54365361535b070c2db7374cec45c159c7d0e7a)
1*e5436536SAndroid Build Coastguard Worker /* -----------------------------------------------------------------------------
2*e5436536SAndroid Build Coastguard Worker Software License for The Fraunhofer FDK AAC Codec Library for Android
3*e5436536SAndroid Build Coastguard Worker 
4*e5436536SAndroid Build Coastguard Worker © Copyright  1995 - 2021 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. Lohwasser
98*e5436536SAndroid Build Coastguard Worker 
99*e5436536SAndroid Build Coastguard Worker    Description: FDK HE-AAC Encoder interface library functions
100*e5436536SAndroid Build Coastguard Worker 
101*e5436536SAndroid Build Coastguard Worker *******************************************************************************/
102*e5436536SAndroid Build Coastguard Worker 
103*e5436536SAndroid Build Coastguard Worker #include "aacenc_lib.h"
104*e5436536SAndroid Build Coastguard Worker #include "FDK_audio.h"
105*e5436536SAndroid Build Coastguard Worker #include "aacenc.h"
106*e5436536SAndroid Build Coastguard Worker 
107*e5436536SAndroid Build Coastguard Worker #include "aacEnc_ram.h"
108*e5436536SAndroid Build Coastguard Worker #include "FDK_core.h" /* FDK_tools versioning info */
109*e5436536SAndroid Build Coastguard Worker 
110*e5436536SAndroid Build Coastguard Worker /* Encoder library info */
111*e5436536SAndroid Build Coastguard Worker #define AACENCODER_LIB_VL0 4
112*e5436536SAndroid Build Coastguard Worker #define AACENCODER_LIB_VL1 0
113*e5436536SAndroid Build Coastguard Worker #define AACENCODER_LIB_VL2 1
114*e5436536SAndroid Build Coastguard Worker #define AACENCODER_LIB_TITLE "AAC Encoder"
115*e5436536SAndroid Build Coastguard Worker #ifdef SUPPRESS_BUILD_DATE_INFO
116*e5436536SAndroid Build Coastguard Worker #define AACENCODER_LIB_BUILD_DATE ""
117*e5436536SAndroid Build Coastguard Worker #define AACENCODER_LIB_BUILD_TIME ""
118*e5436536SAndroid Build Coastguard Worker #else
119*e5436536SAndroid Build Coastguard Worker #define AACENCODER_LIB_BUILD_DATE __DATE__
120*e5436536SAndroid Build Coastguard Worker #define AACENCODER_LIB_BUILD_TIME __TIME__
121*e5436536SAndroid Build Coastguard Worker #endif
122*e5436536SAndroid Build Coastguard Worker 
123*e5436536SAndroid Build Coastguard Worker #include "pcm_utils.h"
124*e5436536SAndroid Build Coastguard Worker 
125*e5436536SAndroid Build Coastguard Worker #include "sbr_encoder.h"
126*e5436536SAndroid Build Coastguard Worker #include "../src/sbrenc_ram.h"
127*e5436536SAndroid Build Coastguard Worker #include "channel_map.h"
128*e5436536SAndroid Build Coastguard Worker 
129*e5436536SAndroid Build Coastguard Worker #include "psy_const.h"
130*e5436536SAndroid Build Coastguard Worker #include "bitenc.h"
131*e5436536SAndroid Build Coastguard Worker 
132*e5436536SAndroid Build Coastguard Worker #include "tpenc_lib.h"
133*e5436536SAndroid Build Coastguard Worker 
134*e5436536SAndroid Build Coastguard Worker #include "metadata_main.h"
135*e5436536SAndroid Build Coastguard Worker #include "mps_main.h"
136*e5436536SAndroid Build Coastguard Worker #include "sacenc_lib.h"
137*e5436536SAndroid Build Coastguard Worker 
138*e5436536SAndroid Build Coastguard Worker #define SBL(fl) \
139*e5436536SAndroid Build Coastguard Worker   (fl /         \
140*e5436536SAndroid Build Coastguard Worker    8) /*!< Short block length (hardcoded to 8 short blocks per long block) */
141*e5436536SAndroid Build Coastguard Worker #define BSLA(fl) \
142*e5436536SAndroid Build Coastguard Worker   (4 * SBL(fl) + SBL(fl) / 2)         /*!< AAC block switching look-ahead */
143*e5436536SAndroid Build Coastguard Worker #define DELAY_AAC(fl) (fl + BSLA(fl)) /*!< MDCT + blockswitching */
144*e5436536SAndroid Build Coastguard Worker #define DELAY_AACLD(fl) (fl) /*!< MDCT delay (no framing delay included) */
145*e5436536SAndroid Build Coastguard Worker #define DELAY_AACELD(fl) \
146*e5436536SAndroid Build Coastguard Worker   ((fl) / 2) /*!< ELD FB delay (no framing delay included) */
147*e5436536SAndroid Build Coastguard Worker 
148*e5436536SAndroid Build Coastguard Worker #define MAX_DS_DELAY (100) /*!< Maximum downsampler delay in SBR. */
149*e5436536SAndroid Build Coastguard Worker #define INPUTBUFFER_SIZE                                                    \
150*e5436536SAndroid Build Coastguard Worker   (2 * (1024) + MAX_DS_DELAY + 1537) /*!< Audio input samples + downsampler \
151*e5436536SAndroid Build Coastguard Worker                                         delay + sbr/aac delay compensation */
152*e5436536SAndroid Build Coastguard Worker 
153*e5436536SAndroid Build Coastguard Worker #define DEFAULT_HEADER_PERIOD_REPETITION_RATE                                  \
154*e5436536SAndroid Build Coastguard Worker   10 /*!< Default header repetition rate used in transport library and for SBR \
155*e5436536SAndroid Build Coastguard Worker         header. */
156*e5436536SAndroid Build Coastguard Worker 
157*e5436536SAndroid Build Coastguard Worker ////////////////////////////////////////////////////////////////////////////////////
158*e5436536SAndroid Build Coastguard Worker /**
159*e5436536SAndroid Build Coastguard Worker  * Flags to characterize encoder modules to be supported in present instance.
160*e5436536SAndroid Build Coastguard Worker  */
161*e5436536SAndroid Build Coastguard Worker enum {
162*e5436536SAndroid Build Coastguard Worker   ENC_MODE_FLAG_AAC = 0x0001,
163*e5436536SAndroid Build Coastguard Worker   ENC_MODE_FLAG_SBR = 0x0002,
164*e5436536SAndroid Build Coastguard Worker   ENC_MODE_FLAG_PS = 0x0004,
165*e5436536SAndroid Build Coastguard Worker   ENC_MODE_FLAG_SAC = 0x0008,
166*e5436536SAndroid Build Coastguard Worker   ENC_MODE_FLAG_META = 0x0010
167*e5436536SAndroid Build Coastguard Worker };
168*e5436536SAndroid Build Coastguard Worker 
169*e5436536SAndroid Build Coastguard Worker ////////////////////////////////////////////////////////////////////////////////////
170*e5436536SAndroid Build Coastguard Worker typedef struct {
171*e5436536SAndroid Build Coastguard Worker   AUDIO_OBJECT_TYPE userAOT; /*!< Audio Object Type.             */
172*e5436536SAndroid Build Coastguard Worker   UINT userSamplerate;       /*!< Sampling frequency.            */
173*e5436536SAndroid Build Coastguard Worker   UINT nChannels;            /*!< will be set via channelMode.   */
174*e5436536SAndroid Build Coastguard Worker   CHANNEL_MODE userChannelMode;
175*e5436536SAndroid Build Coastguard Worker   UINT userBitrate;
176*e5436536SAndroid Build Coastguard Worker   UINT userBitrateMode;
177*e5436536SAndroid Build Coastguard Worker   UINT userBandwidth;
178*e5436536SAndroid Build Coastguard Worker   UINT userAfterburner;
179*e5436536SAndroid Build Coastguard Worker   UINT userFramelength;
180*e5436536SAndroid Build Coastguard Worker   UINT userAncDataRate;
181*e5436536SAndroid Build Coastguard Worker   UINT userPeakBitrate;
182*e5436536SAndroid Build Coastguard Worker 
183*e5436536SAndroid Build Coastguard Worker   UCHAR userTns;       /*!< Use TNS coding. */
184*e5436536SAndroid Build Coastguard Worker   UCHAR userPns;       /*!< Use PNS coding. */
185*e5436536SAndroid Build Coastguard Worker   UCHAR userIntensity; /*!< Use Intensity coding. */
186*e5436536SAndroid Build Coastguard Worker 
187*e5436536SAndroid Build Coastguard Worker   TRANSPORT_TYPE userTpType; /*!< Transport type */
188*e5436536SAndroid Build Coastguard Worker   UCHAR userTpSignaling;     /*!< Extension AOT signaling mode. */
189*e5436536SAndroid Build Coastguard Worker   UCHAR userTpNsubFrames;    /*!< Number of sub frames in a transport frame for
190*e5436536SAndroid Build Coastguard Worker                                 LOAS/LATM or ADTS (default 1). */
191*e5436536SAndroid Build Coastguard Worker   UCHAR userTpAmxv; /*!< AudioMuxVersion to be used for LATM (default 0). */
192*e5436536SAndroid Build Coastguard Worker   UCHAR userTpProtection;
193*e5436536SAndroid Build Coastguard Worker   UCHAR userTpHeaderPeriod; /*!< Parameter used to configure LATM/LOAS SMC rate.
194*e5436536SAndroid Build Coastguard Worker                                Moreover this parameters is used to configure
195*e5436536SAndroid Build Coastguard Worker                                repetition rate of PCE in raw_data_block. */
196*e5436536SAndroid Build Coastguard Worker 
197*e5436536SAndroid Build Coastguard Worker   UCHAR userErTools;     /*!< Use VCB11, HCR and/or RVLC ER tool. */
198*e5436536SAndroid Build Coastguard Worker   UINT userPceAdditions; /*!< Configure additional bits in PCE. */
199*e5436536SAndroid Build Coastguard Worker 
200*e5436536SAndroid Build Coastguard Worker   UCHAR userMetaDataMode; /*!< Meta data library configuration. */
201*e5436536SAndroid Build Coastguard Worker 
202*e5436536SAndroid Build Coastguard Worker   UCHAR userSbrEnabled; /*!< Enable SBR for ELD. */
203*e5436536SAndroid Build Coastguard Worker   UINT userSbrRatio;    /*!< SBR sampling rate ratio. Dual- or single-rate. */
204*e5436536SAndroid Build Coastguard Worker 
205*e5436536SAndroid Build Coastguard Worker   UINT userDownscaleFactor;
206*e5436536SAndroid Build Coastguard Worker 
207*e5436536SAndroid Build Coastguard Worker } USER_PARAM;
208*e5436536SAndroid Build Coastguard Worker 
209*e5436536SAndroid Build Coastguard Worker /**
210*e5436536SAndroid Build Coastguard Worker  *  SBR extenxion payload struct provides buffers to be filled in SBR encoder
211*e5436536SAndroid Build Coastguard Worker  * library.
212*e5436536SAndroid Build Coastguard Worker  */
213*e5436536SAndroid Build Coastguard Worker typedef struct {
214*e5436536SAndroid Build Coastguard Worker   UCHAR data[(1)][(8)][MAX_PAYLOAD_SIZE]; /*!< extension payload data buffer */
215*e5436536SAndroid Build Coastguard Worker   UINT dataSize[(1)][(8)]; /*!< extension payload data size in bits */
216*e5436536SAndroid Build Coastguard Worker } SBRENC_EXT_PAYLOAD;
217*e5436536SAndroid Build Coastguard Worker 
218*e5436536SAndroid Build Coastguard Worker ////////////////////////////////////////////////////////////////////////////////////
219*e5436536SAndroid Build Coastguard Worker 
220*e5436536SAndroid Build Coastguard Worker /****************************************************************************
221*e5436536SAndroid Build Coastguard Worker                            Structure Definitions
222*e5436536SAndroid Build Coastguard Worker ****************************************************************************/
223*e5436536SAndroid Build Coastguard Worker 
224*e5436536SAndroid Build Coastguard Worker typedef struct AACENC_CONFIG *HANDLE_AACENC_CONFIG;
225*e5436536SAndroid Build Coastguard Worker 
226*e5436536SAndroid Build Coastguard Worker struct AACENCODER {
227*e5436536SAndroid Build Coastguard Worker   USER_PARAM extParam;
228*e5436536SAndroid Build Coastguard Worker   CODER_CONFIG coderConfig;
229*e5436536SAndroid Build Coastguard Worker 
230*e5436536SAndroid Build Coastguard Worker   /* AAC */
231*e5436536SAndroid Build Coastguard Worker   AACENC_CONFIG aacConfig;
232*e5436536SAndroid Build Coastguard Worker   HANDLE_AAC_ENC hAacEnc;
233*e5436536SAndroid Build Coastguard Worker 
234*e5436536SAndroid Build Coastguard Worker   /* SBR */
235*e5436536SAndroid Build Coastguard Worker   HANDLE_SBR_ENCODER hEnvEnc;      /* SBR encoder */
236*e5436536SAndroid Build Coastguard Worker   SBRENC_EXT_PAYLOAD *pSbrPayload; /* SBR extension payload */
237*e5436536SAndroid Build Coastguard Worker 
238*e5436536SAndroid Build Coastguard Worker   /* Meta Data */
239*e5436536SAndroid Build Coastguard Worker   HANDLE_FDK_METADATA_ENCODER hMetadataEnc;
240*e5436536SAndroid Build Coastguard Worker   INT metaDataAllowed; /* Signal whether chosen configuration allows metadata.
241*e5436536SAndroid Build Coastguard Worker                           Necessary for delay compensation. Metadata mode is a
242*e5436536SAndroid Build Coastguard Worker                           separate parameter. */
243*e5436536SAndroid Build Coastguard Worker 
244*e5436536SAndroid Build Coastguard Worker   HANDLE_MPS_ENCODER hMpsEnc;
245*e5436536SAndroid Build Coastguard Worker 
246*e5436536SAndroid Build Coastguard Worker   /* Transport */
247*e5436536SAndroid Build Coastguard Worker   HANDLE_TRANSPORTENC hTpEnc;
248*e5436536SAndroid Build Coastguard Worker 
249*e5436536SAndroid Build Coastguard Worker   INT_PCM
250*e5436536SAndroid Build Coastguard Worker   *inputBuffer;     /* Internal input buffer. Input source for AAC encoder */
251*e5436536SAndroid Build Coastguard Worker   UCHAR *outBuffer; /* Internal bitstream buffer */
252*e5436536SAndroid Build Coastguard Worker 
253*e5436536SAndroid Build Coastguard Worker   INT inputBufferSize;           /* Size of internal input buffer */
254*e5436536SAndroid Build Coastguard Worker   INT inputBufferSizePerChannel; /* Size of internal input buffer per channel */
255*e5436536SAndroid Build Coastguard Worker   INT outBufferInBytes;          /* Size of internal bitstream buffer*/
256*e5436536SAndroid Build Coastguard Worker 
257*e5436536SAndroid Build Coastguard Worker   INT inputBufferOffset; /* Where to write new input samples. */
258*e5436536SAndroid Build Coastguard Worker 
259*e5436536SAndroid Build Coastguard Worker   INT nSamplesToRead; /* number of input samples neeeded for encoding one frame
260*e5436536SAndroid Build Coastguard Worker                        */
261*e5436536SAndroid Build Coastguard Worker   INT nSamplesRead;   /* number of input samples already in input buffer */
262*e5436536SAndroid Build Coastguard Worker   INT nZerosAppended; /* appended zeros at end of file*/
263*e5436536SAndroid Build Coastguard Worker   INT nDelay;         /* codec delay */
264*e5436536SAndroid Build Coastguard Worker   INT nDelayCore;     /* codec delay, w/o the SBR decoder delay */
265*e5436536SAndroid Build Coastguard Worker 
266*e5436536SAndroid Build Coastguard Worker   AACENC_EXT_PAYLOAD extPayload[MAX_TOTAL_EXT_PAYLOADS];
267*e5436536SAndroid Build Coastguard Worker 
268*e5436536SAndroid Build Coastguard Worker   ULONG InitFlags; /* internal status to treggier re-initialization */
269*e5436536SAndroid Build Coastguard Worker 
270*e5436536SAndroid Build Coastguard Worker   /* Memory allocation info. */
271*e5436536SAndroid Build Coastguard Worker   INT nMaxAacElements;
272*e5436536SAndroid Build Coastguard Worker   INT nMaxAacChannels;
273*e5436536SAndroid Build Coastguard Worker   INT nMaxSbrElements;
274*e5436536SAndroid Build Coastguard Worker   INT nMaxSbrChannels;
275*e5436536SAndroid Build Coastguard Worker 
276*e5436536SAndroid Build Coastguard Worker   UINT encoder_modis;
277*e5436536SAndroid Build Coastguard Worker 
278*e5436536SAndroid Build Coastguard Worker   /* Capability flags */
279*e5436536SAndroid Build Coastguard Worker   UINT CAPF_tpEnc;
280*e5436536SAndroid Build Coastguard Worker };
281*e5436536SAndroid Build Coastguard Worker 
282*e5436536SAndroid Build Coastguard Worker typedef struct {
283*e5436536SAndroid Build Coastguard Worker   /* input */
284*e5436536SAndroid Build Coastguard Worker   ULONG nChannels;    /*!< Number of audio channels. */
285*e5436536SAndroid Build Coastguard Worker   ULONG samplingRate; /*!< Encoder output sampling rate. */
286*e5436536SAndroid Build Coastguard Worker   ULONG bitrateRange; /*!< Lower bitrate range for config entry. */
287*e5436536SAndroid Build Coastguard Worker 
288*e5436536SAndroid Build Coastguard Worker   /* output*/
289*e5436536SAndroid Build Coastguard Worker   UCHAR sbrMode;       /*!< 0: ELD sbr off,
290*e5436536SAndroid Build Coastguard Worker                             1: ELD with downsampled sbr,
291*e5436536SAndroid Build Coastguard Worker                             2: ELD with dualrate sbr. */
292*e5436536SAndroid Build Coastguard Worker   CHANNEL_MODE chMode; /*!< Channel mode. */
293*e5436536SAndroid Build Coastguard Worker 
294*e5436536SAndroid Build Coastguard Worker } ELD_SBR_CONFIGURATOR;
295*e5436536SAndroid Build Coastguard Worker 
296*e5436536SAndroid Build Coastguard Worker /**
297*e5436536SAndroid Build Coastguard Worker  * \brief  This table defines ELD/SBR default configurations.
298*e5436536SAndroid Build Coastguard Worker  */
299*e5436536SAndroid Build Coastguard Worker static const ELD_SBR_CONFIGURATOR eldSbrAutoConfigTab[] = {
300*e5436536SAndroid Build Coastguard Worker     {1, 48000, 0, 2, MODE_1},      {1, 48000, 64000, 0, MODE_1},
301*e5436536SAndroid Build Coastguard Worker 
302*e5436536SAndroid Build Coastguard Worker     {1, 44100, 0, 2, MODE_1},      {1, 44100, 64000, 0, MODE_1},
303*e5436536SAndroid Build Coastguard Worker 
304*e5436536SAndroid Build Coastguard Worker     {1, 32000, 0, 2, MODE_1},      {1, 32000, 28000, 1, MODE_1},
305*e5436536SAndroid Build Coastguard Worker     {1, 32000, 56000, 0, MODE_1},
306*e5436536SAndroid Build Coastguard Worker 
307*e5436536SAndroid Build Coastguard Worker     {1, 24000, 0, 1, MODE_1},      {1, 24000, 40000, 0, MODE_1},
308*e5436536SAndroid Build Coastguard Worker 
309*e5436536SAndroid Build Coastguard Worker     {1, 16000, 0, 1, MODE_1},      {1, 16000, 28000, 0, MODE_1},
310*e5436536SAndroid Build Coastguard Worker 
311*e5436536SAndroid Build Coastguard Worker     {1, 15999, 0, 0, MODE_1},
312*e5436536SAndroid Build Coastguard Worker 
313*e5436536SAndroid Build Coastguard Worker     {2, 48000, 0, 2, MODE_2},      {2, 48000, 44000, 2, MODE_2},
314*e5436536SAndroid Build Coastguard Worker     {2, 48000, 128000, 0, MODE_2},
315*e5436536SAndroid Build Coastguard Worker 
316*e5436536SAndroid Build Coastguard Worker     {2, 44100, 0, 2, MODE_2},      {2, 44100, 44000, 2, MODE_2},
317*e5436536SAndroid Build Coastguard Worker     {2, 44100, 128000, 0, MODE_2},
318*e5436536SAndroid Build Coastguard Worker 
319*e5436536SAndroid Build Coastguard Worker     {2, 32000, 0, 2, MODE_2},      {2, 32000, 32000, 2, MODE_2},
320*e5436536SAndroid Build Coastguard Worker     {2, 32000, 68000, 1, MODE_2},  {2, 32000, 96000, 0, MODE_2},
321*e5436536SAndroid Build Coastguard Worker 
322*e5436536SAndroid Build Coastguard Worker     {2, 24000, 0, 1, MODE_2},      {2, 24000, 48000, 1, MODE_2},
323*e5436536SAndroid Build Coastguard Worker     {2, 24000, 80000, 0, MODE_2},
324*e5436536SAndroid Build Coastguard Worker 
325*e5436536SAndroid Build Coastguard Worker     {2, 16000, 0, 1, MODE_2},      {2, 16000, 32000, 1, MODE_2},
326*e5436536SAndroid Build Coastguard Worker     {2, 16000, 64000, 0, MODE_2},
327*e5436536SAndroid Build Coastguard Worker 
328*e5436536SAndroid Build Coastguard Worker     {2, 15999, 0, 0, MODE_2}
329*e5436536SAndroid Build Coastguard Worker 
330*e5436536SAndroid Build Coastguard Worker };
331*e5436536SAndroid Build Coastguard Worker 
332*e5436536SAndroid Build Coastguard Worker /*
333*e5436536SAndroid Build Coastguard Worker  * \brief  Configure SBR for ELD configuration.
334*e5436536SAndroid Build Coastguard Worker  *
335*e5436536SAndroid Build Coastguard Worker  * This function finds default SBR configuration for ELD based on number of
336*e5436536SAndroid Build Coastguard Worker  * channels, sampling rate and bitrate.
337*e5436536SAndroid Build Coastguard Worker  *
338*e5436536SAndroid Build Coastguard Worker  * \param nChannels             Number of audio channels.
339*e5436536SAndroid Build Coastguard Worker  * \param samplingRate          Audio signal sampling rate.
340*e5436536SAndroid Build Coastguard Worker  * \param bitrate               Encoder bitrate.
341*e5436536SAndroid Build Coastguard Worker  *
342*e5436536SAndroid Build Coastguard Worker  * \return - pointer to eld sbr configuration.
343*e5436536SAndroid Build Coastguard Worker  *         - NULL, on failure.
344*e5436536SAndroid Build Coastguard Worker  */
eldSbrConfigurator(const ULONG nChannels,const ULONG samplingRate,const ULONG bitrate)345*e5436536SAndroid Build Coastguard Worker static const ELD_SBR_CONFIGURATOR *eldSbrConfigurator(const ULONG nChannels,
346*e5436536SAndroid Build Coastguard Worker                                                       const ULONG samplingRate,
347*e5436536SAndroid Build Coastguard Worker                                                       const ULONG bitrate) {
348*e5436536SAndroid Build Coastguard Worker   int i;
349*e5436536SAndroid Build Coastguard Worker   const ELD_SBR_CONFIGURATOR *pSetup = NULL;
350*e5436536SAndroid Build Coastguard Worker 
351*e5436536SAndroid Build Coastguard Worker   for (i = 0;
352*e5436536SAndroid Build Coastguard Worker        i < (int)(sizeof(eldSbrAutoConfigTab) / sizeof(ELD_SBR_CONFIGURATOR));
353*e5436536SAndroid Build Coastguard Worker        i++) {
354*e5436536SAndroid Build Coastguard Worker     if ((nChannels == eldSbrAutoConfigTab[i].nChannels) &&
355*e5436536SAndroid Build Coastguard Worker         (samplingRate <= eldSbrAutoConfigTab[i].samplingRate) &&
356*e5436536SAndroid Build Coastguard Worker         (bitrate >= eldSbrAutoConfigTab[i].bitrateRange)) {
357*e5436536SAndroid Build Coastguard Worker       pSetup = &eldSbrAutoConfigTab[i];
358*e5436536SAndroid Build Coastguard Worker     }
359*e5436536SAndroid Build Coastguard Worker   }
360*e5436536SAndroid Build Coastguard Worker 
361*e5436536SAndroid Build Coastguard Worker   return pSetup;
362*e5436536SAndroid Build Coastguard Worker }
363*e5436536SAndroid Build Coastguard Worker 
isSbrActive(const HANDLE_AACENC_CONFIG hAacConfig)364*e5436536SAndroid Build Coastguard Worker static inline INT isSbrActive(const HANDLE_AACENC_CONFIG hAacConfig) {
365*e5436536SAndroid Build Coastguard Worker   INT sbrUsed = 0;
366*e5436536SAndroid Build Coastguard Worker 
367*e5436536SAndroid Build Coastguard Worker   /* Note: Even if implicit signalling was selected, The AOT itself here is not
368*e5436536SAndroid Build Coastguard Worker    * AOT_AAC_LC */
369*e5436536SAndroid Build Coastguard Worker   if ((hAacConfig->audioObjectType == AOT_SBR) ||
370*e5436536SAndroid Build Coastguard Worker       (hAacConfig->audioObjectType == AOT_PS) ||
371*e5436536SAndroid Build Coastguard Worker       (hAacConfig->audioObjectType == AOT_MP2_SBR)) {
372*e5436536SAndroid Build Coastguard Worker     sbrUsed = 1;
373*e5436536SAndroid Build Coastguard Worker   }
374*e5436536SAndroid Build Coastguard Worker   if (hAacConfig->audioObjectType == AOT_ER_AAC_ELD &&
375*e5436536SAndroid Build Coastguard Worker       (hAacConfig->syntaxFlags & AC_SBR_PRESENT)) {
376*e5436536SAndroid Build Coastguard Worker     sbrUsed = 1;
377*e5436536SAndroid Build Coastguard Worker   }
378*e5436536SAndroid Build Coastguard Worker 
379*e5436536SAndroid Build Coastguard Worker   return (sbrUsed);
380*e5436536SAndroid Build Coastguard Worker }
381*e5436536SAndroid Build Coastguard Worker 
isPsActive(const AUDIO_OBJECT_TYPE audioObjectType)382*e5436536SAndroid Build Coastguard Worker static inline INT isPsActive(const AUDIO_OBJECT_TYPE audioObjectType) {
383*e5436536SAndroid Build Coastguard Worker   INT psUsed = 0;
384*e5436536SAndroid Build Coastguard Worker 
385*e5436536SAndroid Build Coastguard Worker   if (audioObjectType == AOT_PS) {
386*e5436536SAndroid Build Coastguard Worker     psUsed = 1;
387*e5436536SAndroid Build Coastguard Worker   }
388*e5436536SAndroid Build Coastguard Worker 
389*e5436536SAndroid Build Coastguard Worker   return (psUsed);
390*e5436536SAndroid Build Coastguard Worker }
391*e5436536SAndroid Build Coastguard Worker 
GetCoreChannelMode(const CHANNEL_MODE channelMode,const AUDIO_OBJECT_TYPE audioObjectType)392*e5436536SAndroid Build Coastguard Worker static CHANNEL_MODE GetCoreChannelMode(
393*e5436536SAndroid Build Coastguard Worker     const CHANNEL_MODE channelMode, const AUDIO_OBJECT_TYPE audioObjectType) {
394*e5436536SAndroid Build Coastguard Worker   CHANNEL_MODE mappedChannelMode = channelMode;
395*e5436536SAndroid Build Coastguard Worker   if ((isPsActive(audioObjectType) && (channelMode == MODE_2)) ||
396*e5436536SAndroid Build Coastguard Worker       (channelMode == MODE_212)) {
397*e5436536SAndroid Build Coastguard Worker     mappedChannelMode = MODE_1;
398*e5436536SAndroid Build Coastguard Worker   }
399*e5436536SAndroid Build Coastguard Worker   return mappedChannelMode;
400*e5436536SAndroid Build Coastguard Worker }
401*e5436536SAndroid Build Coastguard Worker 
getSbrSignalingMode(const AUDIO_OBJECT_TYPE audioObjectType,const TRANSPORT_TYPE transportType,const UCHAR transportSignaling,const UINT sbrRatio)402*e5436536SAndroid Build Coastguard Worker static SBR_PS_SIGNALING getSbrSignalingMode(
403*e5436536SAndroid Build Coastguard Worker     const AUDIO_OBJECT_TYPE audioObjectType, const TRANSPORT_TYPE transportType,
404*e5436536SAndroid Build Coastguard Worker     const UCHAR transportSignaling, const UINT sbrRatio)
405*e5436536SAndroid Build Coastguard Worker 
406*e5436536SAndroid Build Coastguard Worker {
407*e5436536SAndroid Build Coastguard Worker   SBR_PS_SIGNALING sbrSignaling;
408*e5436536SAndroid Build Coastguard Worker 
409*e5436536SAndroid Build Coastguard Worker   if (transportType == TT_UNKNOWN || sbrRatio == 0) {
410*e5436536SAndroid Build Coastguard Worker     sbrSignaling = SIG_UNKNOWN; /* Needed parameters have not been set */
411*e5436536SAndroid Build Coastguard Worker     return sbrSignaling;
412*e5436536SAndroid Build Coastguard Worker   } else {
413*e5436536SAndroid Build Coastguard Worker     sbrSignaling =
414*e5436536SAndroid Build Coastguard Worker         SIG_EXPLICIT_HIERARCHICAL; /* default: explicit hierarchical signaling
415*e5436536SAndroid Build Coastguard Worker                                     */
416*e5436536SAndroid Build Coastguard Worker   }
417*e5436536SAndroid Build Coastguard Worker 
418*e5436536SAndroid Build Coastguard Worker   if ((audioObjectType == AOT_AAC_LC) || (audioObjectType == AOT_SBR) ||
419*e5436536SAndroid Build Coastguard Worker       (audioObjectType == AOT_PS) || (audioObjectType == AOT_MP2_AAC_LC) ||
420*e5436536SAndroid Build Coastguard Worker       (audioObjectType == AOT_MP2_SBR)) {
421*e5436536SAndroid Build Coastguard Worker     switch (transportType) {
422*e5436536SAndroid Build Coastguard Worker       case TT_MP4_ADIF:
423*e5436536SAndroid Build Coastguard Worker       case TT_MP4_ADTS:
424*e5436536SAndroid Build Coastguard Worker         sbrSignaling = SIG_IMPLICIT; /* For MPEG-2 transport types, only
425*e5436536SAndroid Build Coastguard Worker                                         implicit signaling is possible */
426*e5436536SAndroid Build Coastguard Worker         break;
427*e5436536SAndroid Build Coastguard Worker 
428*e5436536SAndroid Build Coastguard Worker       case TT_MP4_RAW:
429*e5436536SAndroid Build Coastguard Worker       case TT_MP4_LATM_MCP1:
430*e5436536SAndroid Build Coastguard Worker       case TT_MP4_LATM_MCP0:
431*e5436536SAndroid Build Coastguard Worker       case TT_MP4_LOAS:
432*e5436536SAndroid Build Coastguard Worker       default:
433*e5436536SAndroid Build Coastguard Worker         if (transportSignaling == 0xFF) {
434*e5436536SAndroid Build Coastguard Worker           /* Defaults */
435*e5436536SAndroid Build Coastguard Worker           sbrSignaling = SIG_EXPLICIT_HIERARCHICAL;
436*e5436536SAndroid Build Coastguard Worker         } else {
437*e5436536SAndroid Build Coastguard Worker           /* User set parameters */
438*e5436536SAndroid Build Coastguard Worker           /* Attention: Backward compatible explicit signaling does only work
439*e5436536SAndroid Build Coastguard Worker            * with AMV1 for LATM/LOAS */
440*e5436536SAndroid Build Coastguard Worker           sbrSignaling = (SBR_PS_SIGNALING)transportSignaling;
441*e5436536SAndroid Build Coastguard Worker         }
442*e5436536SAndroid Build Coastguard Worker         break;
443*e5436536SAndroid Build Coastguard Worker     }
444*e5436536SAndroid Build Coastguard Worker   }
445*e5436536SAndroid Build Coastguard Worker 
446*e5436536SAndroid Build Coastguard Worker   return sbrSignaling;
447*e5436536SAndroid Build Coastguard Worker }
448*e5436536SAndroid Build Coastguard Worker 
getAssociatedChElement(SBR_ELEMENT_INFO * elInfoSbr,CHANNEL_MAPPING * channelMapping)449*e5436536SAndroid Build Coastguard Worker static inline INT getAssociatedChElement(SBR_ELEMENT_INFO *elInfoSbr,
450*e5436536SAndroid Build Coastguard Worker                                          CHANNEL_MAPPING *channelMapping) {
451*e5436536SAndroid Build Coastguard Worker   ELEMENT_INFO *elInfo = channelMapping->elInfo;
452*e5436536SAndroid Build Coastguard Worker   INT nElements = channelMapping->nElements;
453*e5436536SAndroid Build Coastguard Worker   INT associatedChElement = -1;
454*e5436536SAndroid Build Coastguard Worker   int i;
455*e5436536SAndroid Build Coastguard Worker 
456*e5436536SAndroid Build Coastguard Worker   for (i = 0; i < nElements; i++) {
457*e5436536SAndroid Build Coastguard Worker     if (elInfoSbr->elType == elInfo[i].elType &&
458*e5436536SAndroid Build Coastguard Worker         elInfoSbr->instanceTag == elInfo[i].instanceTag) {
459*e5436536SAndroid Build Coastguard Worker       associatedChElement = i;
460*e5436536SAndroid Build Coastguard Worker       break;
461*e5436536SAndroid Build Coastguard Worker     }
462*e5436536SAndroid Build Coastguard Worker   }
463*e5436536SAndroid Build Coastguard Worker 
464*e5436536SAndroid Build Coastguard Worker   return associatedChElement;
465*e5436536SAndroid Build Coastguard Worker }
466*e5436536SAndroid Build Coastguard Worker 
467*e5436536SAndroid Build Coastguard Worker /****************************************************************************
468*e5436536SAndroid Build Coastguard Worker                                Allocate Encoder
469*e5436536SAndroid Build Coastguard Worker ****************************************************************************/
470*e5436536SAndroid Build Coastguard Worker 
H_ALLOC_MEM(_AacEncoder,AACENCODER)471*e5436536SAndroid Build Coastguard Worker H_ALLOC_MEM(_AacEncoder, AACENCODER)
472*e5436536SAndroid Build Coastguard Worker C_ALLOC_MEM(_AacEncoder, struct AACENCODER, 1)
473*e5436536SAndroid Build Coastguard Worker 
474*e5436536SAndroid Build Coastguard Worker /*
475*e5436536SAndroid Build Coastguard Worker  * Map Encoder specific config structures to CODER_CONFIG.
476*e5436536SAndroid Build Coastguard Worker  */
477*e5436536SAndroid Build Coastguard Worker static void FDKaacEnc_MapConfig(CODER_CONFIG *const cc,
478*e5436536SAndroid Build Coastguard Worker                                 const USER_PARAM *const extCfg,
479*e5436536SAndroid Build Coastguard Worker                                 const SBR_PS_SIGNALING sbrSignaling,
480*e5436536SAndroid Build Coastguard Worker                                 const HANDLE_AACENC_CONFIG hAacConfig) {
481*e5436536SAndroid Build Coastguard Worker   AUDIO_OBJECT_TYPE transport_AOT = AOT_NULL_OBJECT;
482*e5436536SAndroid Build Coastguard Worker   FDKmemclear(cc, sizeof(CODER_CONFIG));
483*e5436536SAndroid Build Coastguard Worker 
484*e5436536SAndroid Build Coastguard Worker   cc->flags = 0;
485*e5436536SAndroid Build Coastguard Worker 
486*e5436536SAndroid Build Coastguard Worker   cc->samplesPerFrame = hAacConfig->framelength;
487*e5436536SAndroid Build Coastguard Worker   cc->samplingRate = hAacConfig->sampleRate;
488*e5436536SAndroid Build Coastguard Worker   cc->extSamplingRate = extCfg->userSamplerate;
489*e5436536SAndroid Build Coastguard Worker 
490*e5436536SAndroid Build Coastguard Worker   /* Map virtual aot to transport aot. */
491*e5436536SAndroid Build Coastguard Worker   switch (hAacConfig->audioObjectType) {
492*e5436536SAndroid Build Coastguard Worker     case AOT_MP2_AAC_LC:
493*e5436536SAndroid Build Coastguard Worker       transport_AOT = AOT_AAC_LC;
494*e5436536SAndroid Build Coastguard Worker       break;
495*e5436536SAndroid Build Coastguard Worker     case AOT_MP2_SBR:
496*e5436536SAndroid Build Coastguard Worker       transport_AOT = AOT_SBR;
497*e5436536SAndroid Build Coastguard Worker       cc->flags |= CC_SBR;
498*e5436536SAndroid Build Coastguard Worker       break;
499*e5436536SAndroid Build Coastguard Worker     default:
500*e5436536SAndroid Build Coastguard Worker       transport_AOT = hAacConfig->audioObjectType;
501*e5436536SAndroid Build Coastguard Worker   }
502*e5436536SAndroid Build Coastguard Worker 
503*e5436536SAndroid Build Coastguard Worker   if (hAacConfig->audioObjectType == AOT_ER_AAC_ELD) {
504*e5436536SAndroid Build Coastguard Worker     cc->flags |= (hAacConfig->syntaxFlags & AC_SBR_PRESENT) ? CC_SBR : 0;
505*e5436536SAndroid Build Coastguard Worker     cc->flags |= (hAacConfig->syntaxFlags & AC_LD_MPS) ? CC_SAC : 0;
506*e5436536SAndroid Build Coastguard Worker   }
507*e5436536SAndroid Build Coastguard Worker 
508*e5436536SAndroid Build Coastguard Worker   /* transport type is usually AAC-LC. */
509*e5436536SAndroid Build Coastguard Worker   if ((transport_AOT == AOT_SBR) || (transport_AOT == AOT_PS)) {
510*e5436536SAndroid Build Coastguard Worker     cc->aot = AOT_AAC_LC;
511*e5436536SAndroid Build Coastguard Worker   } else {
512*e5436536SAndroid Build Coastguard Worker     cc->aot = transport_AOT;
513*e5436536SAndroid Build Coastguard Worker   }
514*e5436536SAndroid Build Coastguard Worker 
515*e5436536SAndroid Build Coastguard Worker   /* Configure extension aot. */
516*e5436536SAndroid Build Coastguard Worker   if (sbrSignaling == SIG_IMPLICIT) {
517*e5436536SAndroid Build Coastguard Worker     cc->extAOT = AOT_NULL_OBJECT; /* implicit */
518*e5436536SAndroid Build Coastguard Worker   } else {
519*e5436536SAndroid Build Coastguard Worker     if ((sbrSignaling == SIG_EXPLICIT_BW_COMPATIBLE) &&
520*e5436536SAndroid Build Coastguard Worker         ((transport_AOT == AOT_SBR) || (transport_AOT == AOT_PS))) {
521*e5436536SAndroid Build Coastguard Worker       cc->extAOT = AOT_SBR; /* explicit backward compatible */
522*e5436536SAndroid Build Coastguard Worker     } else {
523*e5436536SAndroid Build Coastguard Worker       cc->extAOT = transport_AOT; /* explicit hierarchical */
524*e5436536SAndroid Build Coastguard Worker     }
525*e5436536SAndroid Build Coastguard Worker   }
526*e5436536SAndroid Build Coastguard Worker 
527*e5436536SAndroid Build Coastguard Worker   if ((transport_AOT == AOT_SBR) || (transport_AOT == AOT_PS)) {
528*e5436536SAndroid Build Coastguard Worker     cc->sbrPresent = 1;
529*e5436536SAndroid Build Coastguard Worker     if (transport_AOT == AOT_PS) {
530*e5436536SAndroid Build Coastguard Worker       cc->psPresent = 1;
531*e5436536SAndroid Build Coastguard Worker     }
532*e5436536SAndroid Build Coastguard Worker   }
533*e5436536SAndroid Build Coastguard Worker   cc->sbrSignaling = sbrSignaling;
534*e5436536SAndroid Build Coastguard Worker 
535*e5436536SAndroid Build Coastguard Worker   if (hAacConfig->downscaleFactor > 1) {
536*e5436536SAndroid Build Coastguard Worker     cc->downscaleSamplingRate = cc->samplingRate;
537*e5436536SAndroid Build Coastguard Worker     cc->samplingRate *= hAacConfig->downscaleFactor;
538*e5436536SAndroid Build Coastguard Worker     cc->extSamplingRate *= hAacConfig->downscaleFactor;
539*e5436536SAndroid Build Coastguard Worker   }
540*e5436536SAndroid Build Coastguard Worker 
541*e5436536SAndroid Build Coastguard Worker   cc->bitRate = hAacConfig->bitRate;
542*e5436536SAndroid Build Coastguard Worker   cc->noChannels = hAacConfig->nChannels;
543*e5436536SAndroid Build Coastguard Worker   cc->flags |= CC_IS_BASELAYER;
544*e5436536SAndroid Build Coastguard Worker   cc->channelMode = hAacConfig->channelMode;
545*e5436536SAndroid Build Coastguard Worker 
546*e5436536SAndroid Build Coastguard Worker   cc->nSubFrames = (hAacConfig->nSubFrames > 1 && extCfg->userTpNsubFrames == 1)
547*e5436536SAndroid Build Coastguard Worker                        ? hAacConfig->nSubFrames
548*e5436536SAndroid Build Coastguard Worker                        : extCfg->userTpNsubFrames;
549*e5436536SAndroid Build Coastguard Worker 
550*e5436536SAndroid Build Coastguard Worker   cc->flags |= (extCfg->userTpProtection) ? CC_PROTECTION : 0;
551*e5436536SAndroid Build Coastguard Worker 
552*e5436536SAndroid Build Coastguard Worker   if (extCfg->userTpHeaderPeriod != 0xFF) {
553*e5436536SAndroid Build Coastguard Worker     cc->headerPeriod = extCfg->userTpHeaderPeriod;
554*e5436536SAndroid Build Coastguard Worker   } else { /* auto-mode */
555*e5436536SAndroid Build Coastguard Worker     switch (extCfg->userTpType) {
556*e5436536SAndroid Build Coastguard Worker       case TT_MP4_ADTS:
557*e5436536SAndroid Build Coastguard Worker       case TT_MP4_LOAS:
558*e5436536SAndroid Build Coastguard Worker       case TT_MP4_LATM_MCP1:
559*e5436536SAndroid Build Coastguard Worker         cc->headerPeriod = DEFAULT_HEADER_PERIOD_REPETITION_RATE;
560*e5436536SAndroid Build Coastguard Worker         break;
561*e5436536SAndroid Build Coastguard Worker       default:
562*e5436536SAndroid Build Coastguard Worker         cc->headerPeriod = 0;
563*e5436536SAndroid Build Coastguard Worker     }
564*e5436536SAndroid Build Coastguard Worker   }
565*e5436536SAndroid Build Coastguard Worker 
566*e5436536SAndroid Build Coastguard Worker   /* Mpeg-4 signaling for transport library. */
567*e5436536SAndroid Build Coastguard Worker   switch (hAacConfig->audioObjectType) {
568*e5436536SAndroid Build Coastguard Worker     case AOT_MP2_AAC_LC:
569*e5436536SAndroid Build Coastguard Worker     case AOT_MP2_SBR:
570*e5436536SAndroid Build Coastguard Worker       cc->flags &= ~CC_MPEG_ID; /* Required for ADTS. */
571*e5436536SAndroid Build Coastguard Worker       cc->extAOT = AOT_NULL_OBJECT;
572*e5436536SAndroid Build Coastguard Worker       break;
573*e5436536SAndroid Build Coastguard Worker     default:
574*e5436536SAndroid Build Coastguard Worker       cc->flags |= CC_MPEG_ID;
575*e5436536SAndroid Build Coastguard Worker   }
576*e5436536SAndroid Build Coastguard Worker 
577*e5436536SAndroid Build Coastguard Worker   /* ER-tools signaling. */
578*e5436536SAndroid Build Coastguard Worker   cc->flags |= (hAacConfig->syntaxFlags & AC_ER_VCB11) ? CC_VCB11 : 0;
579*e5436536SAndroid Build Coastguard Worker   cc->flags |= (hAacConfig->syntaxFlags & AC_ER_HCR) ? CC_HCR : 0;
580*e5436536SAndroid Build Coastguard Worker   cc->flags |= (hAacConfig->syntaxFlags & AC_ER_RVLC) ? CC_RVLC : 0;
581*e5436536SAndroid Build Coastguard Worker 
582*e5436536SAndroid Build Coastguard Worker   /* Matrix mixdown coefficient configuration. */
583*e5436536SAndroid Build Coastguard Worker   if ((extCfg->userPceAdditions & 0x1) && (hAacConfig->epConfig == -1) &&
584*e5436536SAndroid Build Coastguard Worker       ((cc->channelMode == MODE_1_2_2) || (cc->channelMode == MODE_1_2_2_1))) {
585*e5436536SAndroid Build Coastguard Worker     cc->matrixMixdownA = ((extCfg->userPceAdditions >> 1) & 0x3) + 1;
586*e5436536SAndroid Build Coastguard Worker     cc->flags |= (extCfg->userPceAdditions >> 3) & 0x1 ? CC_PSEUDO_SURROUND : 0;
587*e5436536SAndroid Build Coastguard Worker   } else {
588*e5436536SAndroid Build Coastguard Worker     cc->matrixMixdownA = 0;
589*e5436536SAndroid Build Coastguard Worker   }
590*e5436536SAndroid Build Coastguard Worker 
591*e5436536SAndroid Build Coastguard Worker   cc->channelConfigZero = 0;
592*e5436536SAndroid Build Coastguard Worker }
593*e5436536SAndroid Build Coastguard Worker 
594*e5436536SAndroid Build Coastguard Worker /*
595*e5436536SAndroid Build Coastguard Worker  * Validate prefilled pointers within buffer descriptor.
596*e5436536SAndroid Build Coastguard Worker  *
597*e5436536SAndroid Build Coastguard Worker  * \param pBufDesc              Pointer to buffer descriptor
598*e5436536SAndroid Build Coastguard Worker 
599*e5436536SAndroid Build Coastguard Worker  * \return - AACENC_OK, all fine.
600*e5436536SAndroid Build Coastguard Worker  *         - AACENC_INVALID_HANDLE, on missing pointer initializiation.
601*e5436536SAndroid Build Coastguard Worker  *         - AACENC_UNSUPPORTED_PARAMETER, on incorrect buffer descriptor
602*e5436536SAndroid Build Coastguard Worker  initialization.
603*e5436536SAndroid Build Coastguard Worker  */
validateBufDesc(const AACENC_BufDesc * pBufDesc)604*e5436536SAndroid Build Coastguard Worker static AACENC_ERROR validateBufDesc(const AACENC_BufDesc *pBufDesc) {
605*e5436536SAndroid Build Coastguard Worker   AACENC_ERROR err = AACENC_OK;
606*e5436536SAndroid Build Coastguard Worker 
607*e5436536SAndroid Build Coastguard Worker   if (pBufDesc != NULL) {
608*e5436536SAndroid Build Coastguard Worker     int i;
609*e5436536SAndroid Build Coastguard Worker     if ((pBufDesc->bufferIdentifiers == NULL) || (pBufDesc->bufSizes == NULL) ||
610*e5436536SAndroid Build Coastguard Worker         (pBufDesc->bufElSizes == NULL) || (pBufDesc->bufs == NULL)) {
611*e5436536SAndroid Build Coastguard Worker       err = AACENC_UNSUPPORTED_PARAMETER;
612*e5436536SAndroid Build Coastguard Worker       goto bail;
613*e5436536SAndroid Build Coastguard Worker     }
614*e5436536SAndroid Build Coastguard Worker     for (i = 0; i < pBufDesc->numBufs; i++) {
615*e5436536SAndroid Build Coastguard Worker       if (pBufDesc->bufs[i] == NULL) {
616*e5436536SAndroid Build Coastguard Worker         err = AACENC_UNSUPPORTED_PARAMETER;
617*e5436536SAndroid Build Coastguard Worker         goto bail;
618*e5436536SAndroid Build Coastguard Worker       }
619*e5436536SAndroid Build Coastguard Worker     }
620*e5436536SAndroid Build Coastguard Worker   } else {
621*e5436536SAndroid Build Coastguard Worker     err = AACENC_INVALID_HANDLE;
622*e5436536SAndroid Build Coastguard Worker   }
623*e5436536SAndroid Build Coastguard Worker bail:
624*e5436536SAndroid Build Coastguard Worker   return err;
625*e5436536SAndroid Build Coastguard Worker }
626*e5436536SAndroid Build Coastguard Worker 
627*e5436536SAndroid Build Coastguard Worker /*
628*e5436536SAndroid Build Coastguard Worker  * Examine buffer descriptor regarding choosen identifier.
629*e5436536SAndroid Build Coastguard Worker  *
630*e5436536SAndroid Build Coastguard Worker  * \param pBufDesc              Pointer to buffer descriptor
631*e5436536SAndroid Build Coastguard Worker  * \param identifier            Buffer identifier to look for.
632*e5436536SAndroid Build Coastguard Worker 
633*e5436536SAndroid Build Coastguard Worker  * \return - Buffer descriptor index.
634*e5436536SAndroid Build Coastguard Worker  *         -1, if there is no entry available.
635*e5436536SAndroid Build Coastguard Worker  */
getBufDescIdx(const AACENC_BufDesc * pBufDesc,const AACENC_BufferIdentifier identifier)636*e5436536SAndroid Build Coastguard Worker static INT getBufDescIdx(const AACENC_BufDesc *pBufDesc,
637*e5436536SAndroid Build Coastguard Worker                          const AACENC_BufferIdentifier identifier) {
638*e5436536SAndroid Build Coastguard Worker   INT i, idx = -1;
639*e5436536SAndroid Build Coastguard Worker 
640*e5436536SAndroid Build Coastguard Worker   if (pBufDesc != NULL) {
641*e5436536SAndroid Build Coastguard Worker     for (i = 0; i < pBufDesc->numBufs; i++) {
642*e5436536SAndroid Build Coastguard Worker       if ((AACENC_BufferIdentifier)pBufDesc->bufferIdentifiers[i] ==
643*e5436536SAndroid Build Coastguard Worker           identifier) {
644*e5436536SAndroid Build Coastguard Worker         idx = i;
645*e5436536SAndroid Build Coastguard Worker         break;
646*e5436536SAndroid Build Coastguard Worker       }
647*e5436536SAndroid Build Coastguard Worker     }
648*e5436536SAndroid Build Coastguard Worker   }
649*e5436536SAndroid Build Coastguard Worker   return idx;
650*e5436536SAndroid Build Coastguard Worker }
651*e5436536SAndroid Build Coastguard Worker 
652*e5436536SAndroid Build Coastguard Worker /****************************************************************************
653*e5436536SAndroid Build Coastguard Worker                           Function Declarations
654*e5436536SAndroid Build Coastguard Worker ****************************************************************************/
655*e5436536SAndroid Build Coastguard Worker 
aacEncDefaultConfig(HANDLE_AACENC_CONFIG hAacConfig,USER_PARAM * config)656*e5436536SAndroid Build Coastguard Worker AAC_ENCODER_ERROR aacEncDefaultConfig(HANDLE_AACENC_CONFIG hAacConfig,
657*e5436536SAndroid Build Coastguard Worker                                       USER_PARAM *config) {
658*e5436536SAndroid Build Coastguard Worker   /* make reasonable default settings */
659*e5436536SAndroid Build Coastguard Worker   FDKaacEnc_AacInitDefaultConfig(hAacConfig);
660*e5436536SAndroid Build Coastguard Worker 
661*e5436536SAndroid Build Coastguard Worker   /* clear configuration structure and copy default settings */
662*e5436536SAndroid Build Coastguard Worker   FDKmemclear(config, sizeof(USER_PARAM));
663*e5436536SAndroid Build Coastguard Worker 
664*e5436536SAndroid Build Coastguard Worker   /* copy encoder configuration settings */
665*e5436536SAndroid Build Coastguard Worker   config->nChannels = hAacConfig->nChannels;
666*e5436536SAndroid Build Coastguard Worker   config->userAOT = hAacConfig->audioObjectType = AOT_AAC_LC;
667*e5436536SAndroid Build Coastguard Worker   config->userSamplerate = hAacConfig->sampleRate;
668*e5436536SAndroid Build Coastguard Worker   config->userChannelMode = hAacConfig->channelMode;
669*e5436536SAndroid Build Coastguard Worker   config->userBitrate = hAacConfig->bitRate;
670*e5436536SAndroid Build Coastguard Worker   config->userBitrateMode = hAacConfig->bitrateMode;
671*e5436536SAndroid Build Coastguard Worker   config->userPeakBitrate = (UINT)-1;
672*e5436536SAndroid Build Coastguard Worker   config->userBandwidth = hAacConfig->bandWidth;
673*e5436536SAndroid Build Coastguard Worker   config->userTns = hAacConfig->useTns;
674*e5436536SAndroid Build Coastguard Worker   config->userPns = hAacConfig->usePns;
675*e5436536SAndroid Build Coastguard Worker   config->userIntensity = hAacConfig->useIS;
676*e5436536SAndroid Build Coastguard Worker   config->userAfterburner = hAacConfig->useRequant;
677*e5436536SAndroid Build Coastguard Worker   config->userFramelength = (UINT)-1;
678*e5436536SAndroid Build Coastguard Worker 
679*e5436536SAndroid Build Coastguard Worker   config->userDownscaleFactor = 1;
680*e5436536SAndroid Build Coastguard Worker 
681*e5436536SAndroid Build Coastguard Worker   /* initialize transport parameters */
682*e5436536SAndroid Build Coastguard Worker   config->userTpType = TT_UNKNOWN;
683*e5436536SAndroid Build Coastguard Worker   config->userTpAmxv = 0;
684*e5436536SAndroid Build Coastguard Worker   config->userTpSignaling = 0xFF; /* choose signaling automatically */
685*e5436536SAndroid Build Coastguard Worker   config->userTpNsubFrames = 1;
686*e5436536SAndroid Build Coastguard Worker   config->userTpProtection = 0;      /* not crc protected*/
687*e5436536SAndroid Build Coastguard Worker   config->userTpHeaderPeriod = 0xFF; /* header period in auto mode */
688*e5436536SAndroid Build Coastguard Worker   config->userPceAdditions = 0;      /* no matrix mixdown coefficient */
689*e5436536SAndroid Build Coastguard Worker   config->userMetaDataMode = 0;      /* do not embed any meta data info */
690*e5436536SAndroid Build Coastguard Worker 
691*e5436536SAndroid Build Coastguard Worker   config->userAncDataRate = 0;
692*e5436536SAndroid Build Coastguard Worker 
693*e5436536SAndroid Build Coastguard Worker   /* SBR rate is set to 0 here, which means it should be set automatically
694*e5436536SAndroid Build Coastguard Worker      in FDKaacEnc_AdjustEncSettings() if the user did not set a rate
695*e5436536SAndroid Build Coastguard Worker      expilicitely. */
696*e5436536SAndroid Build Coastguard Worker   config->userSbrRatio = 0;
697*e5436536SAndroid Build Coastguard Worker 
698*e5436536SAndroid Build Coastguard Worker   /* SBR enable set to -1 means to inquire ELD audio configurator for reasonable
699*e5436536SAndroid Build Coastguard Worker    * configuration. */
700*e5436536SAndroid Build Coastguard Worker   config->userSbrEnabled = (UCHAR)-1;
701*e5436536SAndroid Build Coastguard Worker 
702*e5436536SAndroid Build Coastguard Worker   return AAC_ENC_OK;
703*e5436536SAndroid Build Coastguard Worker }
704*e5436536SAndroid Build Coastguard Worker 
aacEncDistributeSbrBits(CHANNEL_MAPPING * channelMapping,SBR_ELEMENT_INFO * sbrElInfo,INT bitRate)705*e5436536SAndroid Build Coastguard Worker static void aacEncDistributeSbrBits(CHANNEL_MAPPING *channelMapping,
706*e5436536SAndroid Build Coastguard Worker                                     SBR_ELEMENT_INFO *sbrElInfo, INT bitRate) {
707*e5436536SAndroid Build Coastguard Worker   INT codebits = bitRate;
708*e5436536SAndroid Build Coastguard Worker   int el;
709*e5436536SAndroid Build Coastguard Worker 
710*e5436536SAndroid Build Coastguard Worker   /* Copy Element info */
711*e5436536SAndroid Build Coastguard Worker   for (el = 0; el < channelMapping->nElements; el++) {
712*e5436536SAndroid Build Coastguard Worker     sbrElInfo[el].ChannelIndex[0] = channelMapping->elInfo[el].ChannelIndex[0];
713*e5436536SAndroid Build Coastguard Worker     sbrElInfo[el].ChannelIndex[1] = channelMapping->elInfo[el].ChannelIndex[1];
714*e5436536SAndroid Build Coastguard Worker     sbrElInfo[el].elType = channelMapping->elInfo[el].elType;
715*e5436536SAndroid Build Coastguard Worker     sbrElInfo[el].bitRate =
716*e5436536SAndroid Build Coastguard Worker         fMultIfloor(channelMapping->elInfo[el].relativeBits, bitRate);
717*e5436536SAndroid Build Coastguard Worker     sbrElInfo[el].instanceTag = channelMapping->elInfo[el].instanceTag;
718*e5436536SAndroid Build Coastguard Worker     sbrElInfo[el].nChannelsInEl = channelMapping->elInfo[el].nChannelsInEl;
719*e5436536SAndroid Build Coastguard Worker     sbrElInfo[el].fParametricStereo = 0;
720*e5436536SAndroid Build Coastguard Worker     sbrElInfo[el].fDualMono = 0;
721*e5436536SAndroid Build Coastguard Worker 
722*e5436536SAndroid Build Coastguard Worker     codebits -= sbrElInfo[el].bitRate;
723*e5436536SAndroid Build Coastguard Worker   }
724*e5436536SAndroid Build Coastguard Worker   sbrElInfo[0].bitRate += codebits;
725*e5436536SAndroid Build Coastguard Worker }
726*e5436536SAndroid Build Coastguard Worker 
aacEncoder_LimitBitrate(const HANDLE_TRANSPORTENC hTpEnc,const INT samplingRate,const INT frameLength,const INT nChannels,const CHANNEL_MODE channelMode,INT bitRate,const INT nSubFrames,const INT sbrActive,const INT sbrDownSampleRate,const UINT syntaxFlags,const AUDIO_OBJECT_TYPE aot)727*e5436536SAndroid Build Coastguard Worker static INT aacEncoder_LimitBitrate(const HANDLE_TRANSPORTENC hTpEnc,
728*e5436536SAndroid Build Coastguard Worker                                    const INT samplingRate,
729*e5436536SAndroid Build Coastguard Worker                                    const INT frameLength, const INT nChannels,
730*e5436536SAndroid Build Coastguard Worker                                    const CHANNEL_MODE channelMode, INT bitRate,
731*e5436536SAndroid Build Coastguard Worker                                    const INT nSubFrames, const INT sbrActive,
732*e5436536SAndroid Build Coastguard Worker                                    const INT sbrDownSampleRate,
733*e5436536SAndroid Build Coastguard Worker                                    const UINT syntaxFlags,
734*e5436536SAndroid Build Coastguard Worker                                    const AUDIO_OBJECT_TYPE aot) {
735*e5436536SAndroid Build Coastguard Worker   INT coreSamplingRate;
736*e5436536SAndroid Build Coastguard Worker   CHANNEL_MAPPING cm;
737*e5436536SAndroid Build Coastguard Worker 
738*e5436536SAndroid Build Coastguard Worker   FDKaacEnc_InitChannelMapping(channelMode, CH_ORDER_MPEG, &cm);
739*e5436536SAndroid Build Coastguard Worker 
740*e5436536SAndroid Build Coastguard Worker   if (sbrActive) {
741*e5436536SAndroid Build Coastguard Worker     coreSamplingRate =
742*e5436536SAndroid Build Coastguard Worker         samplingRate >>
743*e5436536SAndroid Build Coastguard Worker         (sbrEncoder_IsSingleRatePossible(aot) ? (sbrDownSampleRate - 1) : 1);
744*e5436536SAndroid Build Coastguard Worker   } else {
745*e5436536SAndroid Build Coastguard Worker     coreSamplingRate = samplingRate;
746*e5436536SAndroid Build Coastguard Worker   }
747*e5436536SAndroid Build Coastguard Worker 
748*e5436536SAndroid Build Coastguard Worker   /* Limit bit rate in respect to the core coder */
749*e5436536SAndroid Build Coastguard Worker   bitRate = FDKaacEnc_LimitBitrate(hTpEnc, aot, coreSamplingRate, frameLength,
750*e5436536SAndroid Build Coastguard Worker                                    nChannels, cm.nChannelsEff, bitRate, -1,
751*e5436536SAndroid Build Coastguard Worker                                    NULL, AACENC_BR_MODE_INVALID, nSubFrames);
752*e5436536SAndroid Build Coastguard Worker 
753*e5436536SAndroid Build Coastguard Worker   /* Limit bit rate in respect to available SBR modes if active */
754*e5436536SAndroid Build Coastguard Worker   if (sbrActive) {
755*e5436536SAndroid Build Coastguard Worker     int numIterations = 0;
756*e5436536SAndroid Build Coastguard Worker     INT initialBitrate, adjustedBitrate;
757*e5436536SAndroid Build Coastguard Worker     adjustedBitrate = bitRate;
758*e5436536SAndroid Build Coastguard Worker 
759*e5436536SAndroid Build Coastguard Worker     /* Find total bitrate which provides valid configuration for each SBR
760*e5436536SAndroid Build Coastguard Worker      * element. */
761*e5436536SAndroid Build Coastguard Worker     do {
762*e5436536SAndroid Build Coastguard Worker       int e;
763*e5436536SAndroid Build Coastguard Worker       SBR_ELEMENT_INFO sbrElInfo[((8))];
764*e5436536SAndroid Build Coastguard Worker       FDK_ASSERT(cm.nElements <= ((8)));
765*e5436536SAndroid Build Coastguard Worker 
766*e5436536SAndroid Build Coastguard Worker       initialBitrate = adjustedBitrate;
767*e5436536SAndroid Build Coastguard Worker 
768*e5436536SAndroid Build Coastguard Worker       /* Get bit rate for each SBR element */
769*e5436536SAndroid Build Coastguard Worker       aacEncDistributeSbrBits(&cm, sbrElInfo, initialBitrate);
770*e5436536SAndroid Build Coastguard Worker 
771*e5436536SAndroid Build Coastguard Worker       for (e = 0; e < cm.nElements; e++) {
772*e5436536SAndroid Build Coastguard Worker         INT sbrElementBitRateIn, sbrBitRateOut;
773*e5436536SAndroid Build Coastguard Worker 
774*e5436536SAndroid Build Coastguard Worker         if (cm.elInfo[e].elType != ID_SCE && cm.elInfo[e].elType != ID_CPE) {
775*e5436536SAndroid Build Coastguard Worker           continue;
776*e5436536SAndroid Build Coastguard Worker         }
777*e5436536SAndroid Build Coastguard Worker         sbrElementBitRateIn = sbrElInfo[e].bitRate;
778*e5436536SAndroid Build Coastguard Worker 
779*e5436536SAndroid Build Coastguard Worker         sbrBitRateOut = sbrEncoder_LimitBitRate(sbrElementBitRateIn,
780*e5436536SAndroid Build Coastguard Worker                                                 cm.elInfo[e].nChannelsInEl,
781*e5436536SAndroid Build Coastguard Worker                                                 coreSamplingRate, aot);
782*e5436536SAndroid Build Coastguard Worker 
783*e5436536SAndroid Build Coastguard Worker         if (sbrBitRateOut == 0) {
784*e5436536SAndroid Build Coastguard Worker           return 0;
785*e5436536SAndroid Build Coastguard Worker         }
786*e5436536SAndroid Build Coastguard Worker 
787*e5436536SAndroid Build Coastguard Worker         /* If bitrates don't match, distribution and limiting needs to be
788*e5436536SAndroid Build Coastguard Worker            determined again. Abort element loop and restart with adapted
789*e5436536SAndroid Build Coastguard Worker            bitrate. */
790*e5436536SAndroid Build Coastguard Worker         if (sbrElementBitRateIn != sbrBitRateOut) {
791*e5436536SAndroid Build Coastguard Worker           if (sbrElementBitRateIn < sbrBitRateOut) {
792*e5436536SAndroid Build Coastguard Worker             adjustedBitrate = fMax(initialBitrate,
793*e5436536SAndroid Build Coastguard Worker                                    (INT)fDivNorm((FIXP_DBL)(sbrBitRateOut + 8),
794*e5436536SAndroid Build Coastguard Worker                                                  cm.elInfo[e].relativeBits));
795*e5436536SAndroid Build Coastguard Worker             break;
796*e5436536SAndroid Build Coastguard Worker           }
797*e5436536SAndroid Build Coastguard Worker 
798*e5436536SAndroid Build Coastguard Worker           if (sbrElementBitRateIn > sbrBitRateOut) {
799*e5436536SAndroid Build Coastguard Worker             adjustedBitrate = fMin(initialBitrate,
800*e5436536SAndroid Build Coastguard Worker                                    (INT)fDivNorm((FIXP_DBL)(sbrBitRateOut - 8),
801*e5436536SAndroid Build Coastguard Worker                                                  cm.elInfo[e].relativeBits));
802*e5436536SAndroid Build Coastguard Worker             break;
803*e5436536SAndroid Build Coastguard Worker           }
804*e5436536SAndroid Build Coastguard Worker 
805*e5436536SAndroid Build Coastguard Worker         } /* sbrElementBitRateIn != sbrBitRateOut */
806*e5436536SAndroid Build Coastguard Worker 
807*e5436536SAndroid Build Coastguard Worker       } /* elements */
808*e5436536SAndroid Build Coastguard Worker 
809*e5436536SAndroid Build Coastguard Worker       numIterations++; /* restrict iteration to worst case of num elements */
810*e5436536SAndroid Build Coastguard Worker 
811*e5436536SAndroid Build Coastguard Worker     } while ((initialBitrate != adjustedBitrate) &&
812*e5436536SAndroid Build Coastguard Worker              (numIterations <= cm.nElements));
813*e5436536SAndroid Build Coastguard Worker 
814*e5436536SAndroid Build Coastguard Worker     /* Unequal bitrates mean that no reasonable bitrate configuration found. */
815*e5436536SAndroid Build Coastguard Worker     bitRate = (initialBitrate == adjustedBitrate) ? adjustedBitrate : 0;
816*e5436536SAndroid Build Coastguard Worker   }
817*e5436536SAndroid Build Coastguard Worker 
818*e5436536SAndroid Build Coastguard Worker   /* Limit bit rate in respect to available MPS modes if active */
819*e5436536SAndroid Build Coastguard Worker   if ((aot == AOT_ER_AAC_ELD) && (syntaxFlags & AC_LD_MPS) &&
820*e5436536SAndroid Build Coastguard Worker       (channelMode == MODE_1)) {
821*e5436536SAndroid Build Coastguard Worker     bitRate = FDK_MpegsEnc_GetClosestBitRate(
822*e5436536SAndroid Build Coastguard Worker         aot, MODE_212, samplingRate, (sbrActive) ? sbrDownSampleRate : 0,
823*e5436536SAndroid Build Coastguard Worker         bitRate);
824*e5436536SAndroid Build Coastguard Worker   }
825*e5436536SAndroid Build Coastguard Worker 
826*e5436536SAndroid Build Coastguard Worker   return bitRate;
827*e5436536SAndroid Build Coastguard Worker }
828*e5436536SAndroid Build Coastguard Worker 
829*e5436536SAndroid Build Coastguard Worker /*
830*e5436536SAndroid Build Coastguard Worker  * \brief Get CBR bitrate
831*e5436536SAndroid Build Coastguard Worker  *
832*e5436536SAndroid Build Coastguard Worker  * \hAacConfig Internal encoder config
833*e5436536SAndroid Build Coastguard Worker  * \return     Bitrate
834*e5436536SAndroid Build Coastguard Worker  */
FDKaacEnc_GetCBRBitrate(const HANDLE_AACENC_CONFIG hAacConfig,const INT userSbrRatio)835*e5436536SAndroid Build Coastguard Worker static INT FDKaacEnc_GetCBRBitrate(const HANDLE_AACENC_CONFIG hAacConfig,
836*e5436536SAndroid Build Coastguard Worker                                    const INT userSbrRatio) {
837*e5436536SAndroid Build Coastguard Worker   INT bitrate = FDKaacEnc_GetChannelModeConfiguration(hAacConfig->channelMode)
838*e5436536SAndroid Build Coastguard Worker                     ->nChannelsEff *
839*e5436536SAndroid Build Coastguard Worker                 hAacConfig->sampleRate;
840*e5436536SAndroid Build Coastguard Worker 
841*e5436536SAndroid Build Coastguard Worker   if (isPsActive(hAacConfig->audioObjectType)) {
842*e5436536SAndroid Build Coastguard Worker     bitrate = 1 * bitrate; /* 0.5 bit per sample */
843*e5436536SAndroid Build Coastguard Worker   } else if (isSbrActive(hAacConfig)) {
844*e5436536SAndroid Build Coastguard Worker     if ((userSbrRatio == 2) ||
845*e5436536SAndroid Build Coastguard Worker         ((userSbrRatio == 0) &&
846*e5436536SAndroid Build Coastguard Worker          (hAacConfig->audioObjectType != AOT_ER_AAC_ELD))) {
847*e5436536SAndroid Build Coastguard Worker       bitrate = (bitrate + (bitrate >> 2)) >> 1; /* 0.625 bits per sample */
848*e5436536SAndroid Build Coastguard Worker     }
849*e5436536SAndroid Build Coastguard Worker     if ((userSbrRatio == 1) ||
850*e5436536SAndroid Build Coastguard Worker         ((userSbrRatio == 0) &&
851*e5436536SAndroid Build Coastguard Worker          (hAacConfig->audioObjectType == AOT_ER_AAC_ELD))) {
852*e5436536SAndroid Build Coastguard Worker       bitrate = (bitrate + (bitrate >> 3)); /* 1.125 bits per sample */
853*e5436536SAndroid Build Coastguard Worker     }
854*e5436536SAndroid Build Coastguard Worker   } else {
855*e5436536SAndroid Build Coastguard Worker     bitrate = bitrate + (bitrate >> 1); /* 1.5 bits per sample */
856*e5436536SAndroid Build Coastguard Worker   }
857*e5436536SAndroid Build Coastguard Worker 
858*e5436536SAndroid Build Coastguard Worker   return bitrate;
859*e5436536SAndroid Build Coastguard Worker }
860*e5436536SAndroid Build Coastguard Worker 
861*e5436536SAndroid Build Coastguard Worker /*
862*e5436536SAndroid Build Coastguard Worker  * \brief Consistency check of given USER_PARAM struct and
863*e5436536SAndroid Build Coastguard Worker  *   copy back configuration from public struct into internal
864*e5436536SAndroid Build Coastguard Worker  *   encoder configuration struct.
865*e5436536SAndroid Build Coastguard Worker  *
866*e5436536SAndroid Build Coastguard Worker  * \hAacEncoder Internal encoder config which is to be updated
867*e5436536SAndroid Build Coastguard Worker  * \param config User provided config (public struct)
868*e5436536SAndroid Build Coastguard Worker  * \return returns always AAC_ENC_OK
869*e5436536SAndroid Build Coastguard Worker  */
FDKaacEnc_AdjustEncSettings(HANDLE_AACENCODER hAacEncoder,USER_PARAM * config)870*e5436536SAndroid Build Coastguard Worker static AACENC_ERROR FDKaacEnc_AdjustEncSettings(HANDLE_AACENCODER hAacEncoder,
871*e5436536SAndroid Build Coastguard Worker                                                 USER_PARAM *config) {
872*e5436536SAndroid Build Coastguard Worker   AACENC_ERROR err = AACENC_OK;
873*e5436536SAndroid Build Coastguard Worker 
874*e5436536SAndroid Build Coastguard Worker   /* Get struct pointers. */
875*e5436536SAndroid Build Coastguard Worker   HANDLE_AACENC_CONFIG hAacConfig = &hAacEncoder->aacConfig;
876*e5436536SAndroid Build Coastguard Worker 
877*e5436536SAndroid Build Coastguard Worker   /* Encoder settings update. */
878*e5436536SAndroid Build Coastguard Worker   hAacConfig->sampleRate = config->userSamplerate;
879*e5436536SAndroid Build Coastguard Worker   if (config->userDownscaleFactor > 1) {
880*e5436536SAndroid Build Coastguard Worker     hAacConfig->useTns = 0;
881*e5436536SAndroid Build Coastguard Worker     hAacConfig->usePns = 0;
882*e5436536SAndroid Build Coastguard Worker     hAacConfig->useIS = 0;
883*e5436536SAndroid Build Coastguard Worker   } else {
884*e5436536SAndroid Build Coastguard Worker     hAacConfig->useTns = config->userTns;
885*e5436536SAndroid Build Coastguard Worker     hAacConfig->usePns = config->userPns;
886*e5436536SAndroid Build Coastguard Worker     hAacConfig->useIS = config->userIntensity;
887*e5436536SAndroid Build Coastguard Worker   }
888*e5436536SAndroid Build Coastguard Worker 
889*e5436536SAndroid Build Coastguard Worker   hAacConfig->audioObjectType = config->userAOT;
890*e5436536SAndroid Build Coastguard Worker   hAacConfig->channelMode =
891*e5436536SAndroid Build Coastguard Worker       GetCoreChannelMode(config->userChannelMode, hAacConfig->audioObjectType);
892*e5436536SAndroid Build Coastguard Worker   hAacConfig->nChannels =
893*e5436536SAndroid Build Coastguard Worker       FDKaacEnc_GetChannelModeConfiguration(hAacConfig->channelMode)->nChannels;
894*e5436536SAndroid Build Coastguard Worker   hAacConfig->bitrateMode = (AACENC_BITRATE_MODE)config->userBitrateMode;
895*e5436536SAndroid Build Coastguard Worker   hAacConfig->bandWidth = config->userBandwidth;
896*e5436536SAndroid Build Coastguard Worker   hAacConfig->useRequant = config->userAfterburner;
897*e5436536SAndroid Build Coastguard Worker 
898*e5436536SAndroid Build Coastguard Worker   hAacConfig->anc_Rate = config->userAncDataRate;
899*e5436536SAndroid Build Coastguard Worker   hAacConfig->syntaxFlags = 0;
900*e5436536SAndroid Build Coastguard Worker   hAacConfig->epConfig = -1;
901*e5436536SAndroid Build Coastguard Worker 
902*e5436536SAndroid Build Coastguard Worker   if (hAacConfig->audioObjectType != AOT_ER_AAC_ELD &&
903*e5436536SAndroid Build Coastguard Worker       config->userDownscaleFactor > 1) {
904*e5436536SAndroid Build Coastguard Worker     return AACENC_INVALID_CONFIG; /* downscaling only allowed for AOT_ER_AAC_ELD
905*e5436536SAndroid Build Coastguard Worker                                    */
906*e5436536SAndroid Build Coastguard Worker   }
907*e5436536SAndroid Build Coastguard Worker   if (config->userDownscaleFactor > 1 && config->userSbrEnabled == 1) {
908*e5436536SAndroid Build Coastguard Worker     return AACENC_INVALID_CONFIG; /* downscaling only allowed for AOT_ER_AAC_ELD
909*e5436536SAndroid Build Coastguard Worker                                      w/o SBR */
910*e5436536SAndroid Build Coastguard Worker   }
911*e5436536SAndroid Build Coastguard Worker   if (config->userDownscaleFactor > 1 && config->userChannelMode == 128) {
912*e5436536SAndroid Build Coastguard Worker     return AACENC_INVALID_CONFIG; /* disallow downscaling for AAC-ELDv2 */
913*e5436536SAndroid Build Coastguard Worker   }
914*e5436536SAndroid Build Coastguard Worker 
915*e5436536SAndroid Build Coastguard Worker   if (config->userTpType == TT_MP4_LATM_MCP1 ||
916*e5436536SAndroid Build Coastguard Worker       config->userTpType == TT_MP4_LATM_MCP0 ||
917*e5436536SAndroid Build Coastguard Worker       config->userTpType == TT_MP4_LOAS) {
918*e5436536SAndroid Build Coastguard Worker     hAacConfig->audioMuxVersion = config->userTpAmxv;
919*e5436536SAndroid Build Coastguard Worker   } else {
920*e5436536SAndroid Build Coastguard Worker     hAacConfig->audioMuxVersion = -1;
921*e5436536SAndroid Build Coastguard Worker   }
922*e5436536SAndroid Build Coastguard Worker 
923*e5436536SAndroid Build Coastguard Worker   /* Adapt internal AOT when necessary. */
924*e5436536SAndroid Build Coastguard Worker   switch (config->userAOT) {
925*e5436536SAndroid Build Coastguard Worker     case AOT_MP2_AAC_LC:
926*e5436536SAndroid Build Coastguard Worker     case AOT_MP2_SBR:
927*e5436536SAndroid Build Coastguard Worker       hAacConfig->usePns = 0;
928*e5436536SAndroid Build Coastguard Worker       FDK_FALLTHROUGH;
929*e5436536SAndroid Build Coastguard Worker     case AOT_AAC_LC:
930*e5436536SAndroid Build Coastguard Worker     case AOT_SBR:
931*e5436536SAndroid Build Coastguard Worker     case AOT_PS:
932*e5436536SAndroid Build Coastguard Worker       config->userTpType =
933*e5436536SAndroid Build Coastguard Worker           (config->userTpType != TT_UNKNOWN) ? config->userTpType : TT_MP4_ADTS;
934*e5436536SAndroid Build Coastguard Worker       hAacConfig->framelength = (config->userFramelength != (UINT)-1)
935*e5436536SAndroid Build Coastguard Worker                                     ? config->userFramelength
936*e5436536SAndroid Build Coastguard Worker                                     : 1024;
937*e5436536SAndroid Build Coastguard Worker       if (hAacConfig->framelength != 1024 && hAacConfig->framelength != 960) {
938*e5436536SAndroid Build Coastguard Worker         return AACENC_INVALID_CONFIG;
939*e5436536SAndroid Build Coastguard Worker       }
940*e5436536SAndroid Build Coastguard Worker       break;
941*e5436536SAndroid Build Coastguard Worker     case AOT_ER_AAC_LD:
942*e5436536SAndroid Build Coastguard Worker       hAacConfig->epConfig = 0;
943*e5436536SAndroid Build Coastguard Worker       hAacConfig->syntaxFlags |= AC_ER | AC_LD;
944*e5436536SAndroid Build Coastguard Worker       hAacConfig->syntaxFlags |=
945*e5436536SAndroid Build Coastguard Worker           ((config->userErTools & 0x1) ? AC_ER_VCB11 : 0);
946*e5436536SAndroid Build Coastguard Worker       hAacConfig->syntaxFlags |= ((config->userErTools & 0x2) ? AC_ER_HCR : 0);
947*e5436536SAndroid Build Coastguard Worker       hAacConfig->syntaxFlags |= ((config->userErTools & 0x4) ? AC_ER_RVLC : 0);
948*e5436536SAndroid Build Coastguard Worker       config->userTpType =
949*e5436536SAndroid Build Coastguard Worker           (config->userTpType != TT_UNKNOWN) ? config->userTpType : TT_MP4_LOAS;
950*e5436536SAndroid Build Coastguard Worker       hAacConfig->framelength =
951*e5436536SAndroid Build Coastguard Worker           (config->userFramelength != (UINT)-1) ? config->userFramelength : 512;
952*e5436536SAndroid Build Coastguard Worker       if (hAacConfig->framelength != 512 && hAacConfig->framelength != 480) {
953*e5436536SAndroid Build Coastguard Worker         return AACENC_INVALID_CONFIG;
954*e5436536SAndroid Build Coastguard Worker       }
955*e5436536SAndroid Build Coastguard Worker       break;
956*e5436536SAndroid Build Coastguard Worker     case AOT_ER_AAC_ELD:
957*e5436536SAndroid Build Coastguard Worker       hAacConfig->epConfig = 0;
958*e5436536SAndroid Build Coastguard Worker       hAacConfig->syntaxFlags |= AC_ER | AC_ELD;
959*e5436536SAndroid Build Coastguard Worker       hAacConfig->syntaxFlags |=
960*e5436536SAndroid Build Coastguard Worker           ((config->userErTools & 0x1) ? AC_ER_VCB11 : 0);
961*e5436536SAndroid Build Coastguard Worker       hAacConfig->syntaxFlags |= ((config->userErTools & 0x2) ? AC_ER_HCR : 0);
962*e5436536SAndroid Build Coastguard Worker       hAacConfig->syntaxFlags |= ((config->userErTools & 0x4) ? AC_ER_RVLC : 0);
963*e5436536SAndroid Build Coastguard Worker       hAacConfig->syntaxFlags |=
964*e5436536SAndroid Build Coastguard Worker           ((config->userSbrEnabled == 1) ? AC_SBR_PRESENT : 0);
965*e5436536SAndroid Build Coastguard Worker       hAacConfig->syntaxFlags |=
966*e5436536SAndroid Build Coastguard Worker           ((config->userChannelMode == MODE_212) ? AC_LD_MPS : 0);
967*e5436536SAndroid Build Coastguard Worker       config->userTpType =
968*e5436536SAndroid Build Coastguard Worker           (config->userTpType != TT_UNKNOWN) ? config->userTpType : TT_MP4_LOAS;
969*e5436536SAndroid Build Coastguard Worker       hAacConfig->framelength =
970*e5436536SAndroid Build Coastguard Worker           (config->userFramelength != (UINT)-1) ? config->userFramelength : 512;
971*e5436536SAndroid Build Coastguard Worker 
972*e5436536SAndroid Build Coastguard Worker       hAacConfig->downscaleFactor = config->userDownscaleFactor;
973*e5436536SAndroid Build Coastguard Worker 
974*e5436536SAndroid Build Coastguard Worker       switch (config->userDownscaleFactor) {
975*e5436536SAndroid Build Coastguard Worker         case 1:
976*e5436536SAndroid Build Coastguard Worker           break;
977*e5436536SAndroid Build Coastguard Worker         case 2:
978*e5436536SAndroid Build Coastguard Worker         case 4:
979*e5436536SAndroid Build Coastguard Worker           hAacConfig->syntaxFlags |= AC_ELD_DOWNSCALE;
980*e5436536SAndroid Build Coastguard Worker           break;
981*e5436536SAndroid Build Coastguard Worker         default:
982*e5436536SAndroid Build Coastguard Worker           return AACENC_INVALID_CONFIG;
983*e5436536SAndroid Build Coastguard Worker       }
984*e5436536SAndroid Build Coastguard Worker 
985*e5436536SAndroid Build Coastguard Worker       if (hAacConfig->framelength != 512 && hAacConfig->framelength != 480 &&
986*e5436536SAndroid Build Coastguard Worker           hAacConfig->framelength != 256 && hAacConfig->framelength != 240 &&
987*e5436536SAndroid Build Coastguard Worker           hAacConfig->framelength != 128 && hAacConfig->framelength != 120) {
988*e5436536SAndroid Build Coastguard Worker         return AACENC_INVALID_CONFIG;
989*e5436536SAndroid Build Coastguard Worker       }
990*e5436536SAndroid Build Coastguard Worker       break;
991*e5436536SAndroid Build Coastguard Worker     default:
992*e5436536SAndroid Build Coastguard Worker       break;
993*e5436536SAndroid Build Coastguard Worker   }
994*e5436536SAndroid Build Coastguard Worker 
995*e5436536SAndroid Build Coastguard Worker   /* Initialize SBR parameters */
996*e5436536SAndroid Build Coastguard Worker   if ((config->userSbrRatio == 0) && (isSbrActive(hAacConfig))) {
997*e5436536SAndroid Build Coastguard Worker     /* Automatic SBR ratio configuration
998*e5436536SAndroid Build Coastguard Worker      * - downsampled SBR for ELD
999*e5436536SAndroid Build Coastguard Worker      * - otherwise always dualrate SBR
1000*e5436536SAndroid Build Coastguard Worker      */
1001*e5436536SAndroid Build Coastguard Worker     if (hAacConfig->audioObjectType == AOT_ER_AAC_ELD) {
1002*e5436536SAndroid Build Coastguard Worker       hAacConfig->sbrRatio = ((hAacConfig->syntaxFlags & AC_LD_MPS) &&
1003*e5436536SAndroid Build Coastguard Worker                               (hAacConfig->sampleRate >= 27713))
1004*e5436536SAndroid Build Coastguard Worker                                  ? 2
1005*e5436536SAndroid Build Coastguard Worker                                  : 1;
1006*e5436536SAndroid Build Coastguard Worker     } else {
1007*e5436536SAndroid Build Coastguard Worker       hAacConfig->sbrRatio = 2;
1008*e5436536SAndroid Build Coastguard Worker     }
1009*e5436536SAndroid Build Coastguard Worker   } else {
1010*e5436536SAndroid Build Coastguard Worker     /* SBR ratio has been set by the user, so use it. */
1011*e5436536SAndroid Build Coastguard Worker     hAacConfig->sbrRatio = isSbrActive(hAacConfig) ? config->userSbrRatio : 0;
1012*e5436536SAndroid Build Coastguard Worker   }
1013*e5436536SAndroid Build Coastguard Worker 
1014*e5436536SAndroid Build Coastguard Worker   /* Set default bitrate */
1015*e5436536SAndroid Build Coastguard Worker   hAacConfig->bitRate = config->userBitrate;
1016*e5436536SAndroid Build Coastguard Worker 
1017*e5436536SAndroid Build Coastguard Worker   switch (hAacConfig->bitrateMode) {
1018*e5436536SAndroid Build Coastguard Worker     case AACENC_BR_MODE_CBR:
1019*e5436536SAndroid Build Coastguard Worker       /* Set default bitrate if no external bitrate declared. */
1020*e5436536SAndroid Build Coastguard Worker       if (config->userBitrate == (UINT)-1) {
1021*e5436536SAndroid Build Coastguard Worker         hAacConfig->bitRate =
1022*e5436536SAndroid Build Coastguard Worker             FDKaacEnc_GetCBRBitrate(hAacConfig, config->userSbrRatio);
1023*e5436536SAndroid Build Coastguard Worker       }
1024*e5436536SAndroid Build Coastguard Worker       hAacConfig->averageBits = -1;
1025*e5436536SAndroid Build Coastguard Worker       break;
1026*e5436536SAndroid Build Coastguard Worker     case AACENC_BR_MODE_VBR_1:
1027*e5436536SAndroid Build Coastguard Worker     case AACENC_BR_MODE_VBR_2:
1028*e5436536SAndroid Build Coastguard Worker     case AACENC_BR_MODE_VBR_3:
1029*e5436536SAndroid Build Coastguard Worker     case AACENC_BR_MODE_VBR_4:
1030*e5436536SAndroid Build Coastguard Worker     case AACENC_BR_MODE_VBR_5:
1031*e5436536SAndroid Build Coastguard Worker       /* Adjust bitrate mode in case given peak bitrate is lower than expected
1032*e5436536SAndroid Build Coastguard Worker        * VBR bitrate. */
1033*e5436536SAndroid Build Coastguard Worker       if ((INT)config->userPeakBitrate != -1) {
1034*e5436536SAndroid Build Coastguard Worker         hAacConfig->bitrateMode = FDKaacEnc_AdjustVBRBitrateMode(
1035*e5436536SAndroid Build Coastguard Worker             hAacConfig->bitrateMode, config->userPeakBitrate,
1036*e5436536SAndroid Build Coastguard Worker             hAacConfig->channelMode);
1037*e5436536SAndroid Build Coastguard Worker       }
1038*e5436536SAndroid Build Coastguard Worker       /* Get bitrate in VBR configuration */
1039*e5436536SAndroid Build Coastguard Worker       /* In VBR mode; SBR-modul depends on bitrate, core encoder on bitrateMode.
1040*e5436536SAndroid Build Coastguard Worker        */
1041*e5436536SAndroid Build Coastguard Worker       hAacConfig->bitRate = FDKaacEnc_GetVBRBitrate(hAacConfig->bitrateMode,
1042*e5436536SAndroid Build Coastguard Worker                                                     hAacConfig->channelMode);
1043*e5436536SAndroid Build Coastguard Worker       break;
1044*e5436536SAndroid Build Coastguard Worker     default:
1045*e5436536SAndroid Build Coastguard Worker       return AACENC_INVALID_CONFIG;
1046*e5436536SAndroid Build Coastguard Worker   }
1047*e5436536SAndroid Build Coastguard Worker 
1048*e5436536SAndroid Build Coastguard Worker   /* set bitreservoir size */
1049*e5436536SAndroid Build Coastguard Worker   switch (hAacConfig->bitrateMode) {
1050*e5436536SAndroid Build Coastguard Worker     case AACENC_BR_MODE_VBR_1:
1051*e5436536SAndroid Build Coastguard Worker     case AACENC_BR_MODE_VBR_2:
1052*e5436536SAndroid Build Coastguard Worker     case AACENC_BR_MODE_VBR_3:
1053*e5436536SAndroid Build Coastguard Worker     case AACENC_BR_MODE_VBR_4:
1054*e5436536SAndroid Build Coastguard Worker     case AACENC_BR_MODE_VBR_5:
1055*e5436536SAndroid Build Coastguard Worker     case AACENC_BR_MODE_CBR:
1056*e5436536SAndroid Build Coastguard Worker       if ((INT)config->userPeakBitrate != -1) {
1057*e5436536SAndroid Build Coastguard Worker         hAacConfig->maxBitsPerFrame =
1058*e5436536SAndroid Build Coastguard Worker             (FDKaacEnc_CalcBitsPerFrame(
1059*e5436536SAndroid Build Coastguard Worker                  fMax(hAacConfig->bitRate, (INT)config->userPeakBitrate),
1060*e5436536SAndroid Build Coastguard Worker                  hAacConfig->framelength, hAacConfig->sampleRate) +
1061*e5436536SAndroid Build Coastguard Worker              7) &
1062*e5436536SAndroid Build Coastguard Worker             ~7;
1063*e5436536SAndroid Build Coastguard Worker       } else {
1064*e5436536SAndroid Build Coastguard Worker         hAacConfig->maxBitsPerFrame = -1;
1065*e5436536SAndroid Build Coastguard Worker       }
1066*e5436536SAndroid Build Coastguard Worker       if (hAacConfig->audioMuxVersion == 2) {
1067*e5436536SAndroid Build Coastguard Worker         hAacConfig->minBitsPerFrame =
1068*e5436536SAndroid Build Coastguard Worker             fMin(32 * 8, FDKaacEnc_CalcBitsPerFrame(hAacConfig->bitRate,
1069*e5436536SAndroid Build Coastguard Worker                                                     hAacConfig->framelength,
1070*e5436536SAndroid Build Coastguard Worker                                                     hAacConfig->sampleRate)) &
1071*e5436536SAndroid Build Coastguard Worker             ~7;
1072*e5436536SAndroid Build Coastguard Worker       }
1073*e5436536SAndroid Build Coastguard Worker       break;
1074*e5436536SAndroid Build Coastguard Worker     default:
1075*e5436536SAndroid Build Coastguard Worker       return AACENC_INVALID_CONFIG;
1076*e5436536SAndroid Build Coastguard Worker   }
1077*e5436536SAndroid Build Coastguard Worker 
1078*e5436536SAndroid Build Coastguard Worker   /* Max bits per frame limitation depending on transport format. */
1079*e5436536SAndroid Build Coastguard Worker   if ((config->userTpNsubFrames > 1)) {
1080*e5436536SAndroid Build Coastguard Worker     int maxFrameLength = 8 * hAacEncoder->outBufferInBytes;
1081*e5436536SAndroid Build Coastguard Worker     switch (config->userTpType) {
1082*e5436536SAndroid Build Coastguard Worker       case TT_MP4_LOAS:
1083*e5436536SAndroid Build Coastguard Worker         maxFrameLength =
1084*e5436536SAndroid Build Coastguard Worker             fMin(maxFrameLength, 8 * (1 << 13)) / config->userTpNsubFrames;
1085*e5436536SAndroid Build Coastguard Worker         break;
1086*e5436536SAndroid Build Coastguard Worker       case TT_MP4_ADTS:
1087*e5436536SAndroid Build Coastguard Worker         maxFrameLength = fMin(maxFrameLength, 8 * ((1 << 13) - 1)) /
1088*e5436536SAndroid Build Coastguard Worker                          config->userTpNsubFrames;
1089*e5436536SAndroid Build Coastguard Worker         break;
1090*e5436536SAndroid Build Coastguard Worker       default:
1091*e5436536SAndroid Build Coastguard Worker         maxFrameLength = -1;
1092*e5436536SAndroid Build Coastguard Worker     }
1093*e5436536SAndroid Build Coastguard Worker     if (maxFrameLength != -1) {
1094*e5436536SAndroid Build Coastguard Worker       if (hAacConfig->maxBitsPerFrame > maxFrameLength) {
1095*e5436536SAndroid Build Coastguard Worker         return AACENC_INVALID_CONFIG;
1096*e5436536SAndroid Build Coastguard Worker       } else if (hAacConfig->maxBitsPerFrame == -1) {
1097*e5436536SAndroid Build Coastguard Worker         hAacConfig->maxBitsPerFrame = maxFrameLength;
1098*e5436536SAndroid Build Coastguard Worker       }
1099*e5436536SAndroid Build Coastguard Worker     }
1100*e5436536SAndroid Build Coastguard Worker   }
1101*e5436536SAndroid Build Coastguard Worker 
1102*e5436536SAndroid Build Coastguard Worker   if ((hAacConfig->audioObjectType == AOT_ER_AAC_ELD) &&
1103*e5436536SAndroid Build Coastguard Worker       !(hAacConfig->syntaxFlags & AC_ELD_DOWNSCALE) &&
1104*e5436536SAndroid Build Coastguard Worker       (config->userSbrEnabled == (UCHAR)-1) && (config->userSbrRatio == 0) &&
1105*e5436536SAndroid Build Coastguard Worker       ((hAacConfig->syntaxFlags & AC_LD_MPS) == 0)) {
1106*e5436536SAndroid Build Coastguard Worker     const ELD_SBR_CONFIGURATOR *pConfig = NULL;
1107*e5436536SAndroid Build Coastguard Worker 
1108*e5436536SAndroid Build Coastguard Worker     if (NULL !=
1109*e5436536SAndroid Build Coastguard Worker         (pConfig = eldSbrConfigurator(
1110*e5436536SAndroid Build Coastguard Worker              FDKaacEnc_GetChannelModeConfiguration(hAacConfig->channelMode)
1111*e5436536SAndroid Build Coastguard Worker                  ->nChannels,
1112*e5436536SAndroid Build Coastguard Worker              hAacConfig->sampleRate, hAacConfig->bitRate))) {
1113*e5436536SAndroid Build Coastguard Worker       hAacConfig->syntaxFlags |= (pConfig->sbrMode == 0) ? 0 : AC_SBR_PRESENT;
1114*e5436536SAndroid Build Coastguard Worker       hAacConfig->syntaxFlags |= (pConfig->chMode == MODE_212) ? AC_LD_MPS : 0;
1115*e5436536SAndroid Build Coastguard Worker       hAacConfig->channelMode =
1116*e5436536SAndroid Build Coastguard Worker           GetCoreChannelMode(pConfig->chMode, hAacConfig->audioObjectType);
1117*e5436536SAndroid Build Coastguard Worker       hAacConfig->nChannels =
1118*e5436536SAndroid Build Coastguard Worker           FDKaacEnc_GetChannelModeConfiguration(hAacConfig->channelMode)
1119*e5436536SAndroid Build Coastguard Worker               ->nChannels;
1120*e5436536SAndroid Build Coastguard Worker       hAacConfig->sbrRatio =
1121*e5436536SAndroid Build Coastguard Worker           (pConfig->sbrMode == 0) ? 0 : (pConfig->sbrMode == 1) ? 1 : 2;
1122*e5436536SAndroid Build Coastguard Worker     }
1123*e5436536SAndroid Build Coastguard Worker   }
1124*e5436536SAndroid Build Coastguard Worker 
1125*e5436536SAndroid Build Coastguard Worker   {
1126*e5436536SAndroid Build Coastguard Worker     UCHAR tpSignaling =
1127*e5436536SAndroid Build Coastguard Worker         getSbrSignalingMode(hAacConfig->audioObjectType, config->userTpType,
1128*e5436536SAndroid Build Coastguard Worker                             config->userTpSignaling, hAacConfig->sbrRatio);
1129*e5436536SAndroid Build Coastguard Worker 
1130*e5436536SAndroid Build Coastguard Worker     if ((hAacConfig->audioObjectType == AOT_AAC_LC ||
1131*e5436536SAndroid Build Coastguard Worker          hAacConfig->audioObjectType == AOT_SBR ||
1132*e5436536SAndroid Build Coastguard Worker          hAacConfig->audioObjectType == AOT_PS) &&
1133*e5436536SAndroid Build Coastguard Worker         (config->userTpType == TT_MP4_LATM_MCP1 ||
1134*e5436536SAndroid Build Coastguard Worker          config->userTpType == TT_MP4_LATM_MCP0 ||
1135*e5436536SAndroid Build Coastguard Worker          config->userTpType == TT_MP4_LOAS) &&
1136*e5436536SAndroid Build Coastguard Worker         (tpSignaling == 1) && (config->userTpAmxv == 0)) {
1137*e5436536SAndroid Build Coastguard Worker       /* For backward compatible explicit signaling, AMV1 has to be active */
1138*e5436536SAndroid Build Coastguard Worker       return AACENC_INVALID_CONFIG;
1139*e5436536SAndroid Build Coastguard Worker     }
1140*e5436536SAndroid Build Coastguard Worker 
1141*e5436536SAndroid Build Coastguard Worker     if ((hAacConfig->audioObjectType == AOT_AAC_LC ||
1142*e5436536SAndroid Build Coastguard Worker          hAacConfig->audioObjectType == AOT_SBR ||
1143*e5436536SAndroid Build Coastguard Worker          hAacConfig->audioObjectType == AOT_PS) &&
1144*e5436536SAndroid Build Coastguard Worker         (tpSignaling == 0) && (hAacConfig->sbrRatio == 1)) {
1145*e5436536SAndroid Build Coastguard Worker       /* Downsampled SBR has to be signaled explicitely (for transmission of SBR
1146*e5436536SAndroid Build Coastguard Worker        * sampling fequency) */
1147*e5436536SAndroid Build Coastguard Worker       return AACENC_INVALID_CONFIG;
1148*e5436536SAndroid Build Coastguard Worker     }
1149*e5436536SAndroid Build Coastguard Worker   }
1150*e5436536SAndroid Build Coastguard Worker 
1151*e5436536SAndroid Build Coastguard Worker   switch (hAacConfig->bitrateMode) {
1152*e5436536SAndroid Build Coastguard Worker     case AACENC_BR_MODE_CBR:
1153*e5436536SAndroid Build Coastguard Worker     case AACENC_BR_MODE_VBR_1:
1154*e5436536SAndroid Build Coastguard Worker     case AACENC_BR_MODE_VBR_2:
1155*e5436536SAndroid Build Coastguard Worker     case AACENC_BR_MODE_VBR_3:
1156*e5436536SAndroid Build Coastguard Worker     case AACENC_BR_MODE_VBR_4:
1157*e5436536SAndroid Build Coastguard Worker     case AACENC_BR_MODE_VBR_5:
1158*e5436536SAndroid Build Coastguard Worker       /* We need the frame length to call aacEncoder_LimitBitrate() */
1159*e5436536SAndroid Build Coastguard Worker       if (0 >= (hAacConfig->bitRate = aacEncoder_LimitBitrate(
1160*e5436536SAndroid Build Coastguard Worker                     NULL, hAacConfig->sampleRate, hAacConfig->framelength,
1161*e5436536SAndroid Build Coastguard Worker                     hAacConfig->nChannels, hAacConfig->channelMode,
1162*e5436536SAndroid Build Coastguard Worker                     hAacConfig->bitRate, hAacConfig->nSubFrames,
1163*e5436536SAndroid Build Coastguard Worker                     isSbrActive(hAacConfig), hAacConfig->sbrRatio,
1164*e5436536SAndroid Build Coastguard Worker                     hAacConfig->syntaxFlags, hAacConfig->audioObjectType))) {
1165*e5436536SAndroid Build Coastguard Worker         return AACENC_INVALID_CONFIG;
1166*e5436536SAndroid Build Coastguard Worker       }
1167*e5436536SAndroid Build Coastguard Worker       break;
1168*e5436536SAndroid Build Coastguard Worker     default:
1169*e5436536SAndroid Build Coastguard Worker       break;
1170*e5436536SAndroid Build Coastguard Worker   }
1171*e5436536SAndroid Build Coastguard Worker 
1172*e5436536SAndroid Build Coastguard Worker   /* Configure PNS */
1173*e5436536SAndroid Build Coastguard Worker   if (AACENC_BR_MODE_IS_VBR(hAacConfig->bitrateMode) /* VBR without PNS. */
1174*e5436536SAndroid Build Coastguard Worker       || (hAacConfig->useTns == 0))                  /* TNS required.    */
1175*e5436536SAndroid Build Coastguard Worker   {
1176*e5436536SAndroid Build Coastguard Worker     hAacConfig->usePns = 0;
1177*e5436536SAndroid Build Coastguard Worker   }
1178*e5436536SAndroid Build Coastguard Worker 
1179*e5436536SAndroid Build Coastguard Worker   if (hAacConfig->epConfig >= 0) {
1180*e5436536SAndroid Build Coastguard Worker     hAacConfig->syntaxFlags |= AC_ER;
1181*e5436536SAndroid Build Coastguard Worker     if (((INT)hAacConfig->channelMode < 1) ||
1182*e5436536SAndroid Build Coastguard Worker         ((INT)hAacConfig->channelMode > 14)) {
1183*e5436536SAndroid Build Coastguard Worker       return AACENC_INVALID_CONFIG; /* Channel config 0 not supported. */
1184*e5436536SAndroid Build Coastguard Worker     }
1185*e5436536SAndroid Build Coastguard Worker   }
1186*e5436536SAndroid Build Coastguard Worker 
1187*e5436536SAndroid Build Coastguard Worker   if ((hAacConfig->syntaxFlags & AC_LD_MPS) == 0) {
1188*e5436536SAndroid Build Coastguard Worker     if (FDKaacEnc_DetermineEncoderMode(&hAacConfig->channelMode,
1189*e5436536SAndroid Build Coastguard Worker                                        hAacConfig->nChannels) != AAC_ENC_OK) {
1190*e5436536SAndroid Build Coastguard Worker       return AACENC_INVALID_CONFIG; /* nChannels doesn't match chMode, this is
1191*e5436536SAndroid Build Coastguard Worker                                        just a check-up */
1192*e5436536SAndroid Build Coastguard Worker     }
1193*e5436536SAndroid Build Coastguard Worker   }
1194*e5436536SAndroid Build Coastguard Worker 
1195*e5436536SAndroid Build Coastguard Worker   if ((hAacConfig->nChannels > hAacEncoder->nMaxAacChannels) ||
1196*e5436536SAndroid Build Coastguard Worker       ((FDKaacEnc_GetChannelModeConfiguration(hAacConfig->channelMode)
1197*e5436536SAndroid Build Coastguard Worker             ->nChannelsEff > hAacEncoder->nMaxSbrChannels) &&
1198*e5436536SAndroid Build Coastguard Worker        isSbrActive(hAacConfig))) {
1199*e5436536SAndroid Build Coastguard Worker     return AACENC_INVALID_CONFIG; /* not enough channels allocated */
1200*e5436536SAndroid Build Coastguard Worker   }
1201*e5436536SAndroid Build Coastguard Worker 
1202*e5436536SAndroid Build Coastguard Worker   /* Meta data restriction. */
1203*e5436536SAndroid Build Coastguard Worker   switch (hAacConfig->audioObjectType) {
1204*e5436536SAndroid Build Coastguard Worker     /* Allow metadata support */
1205*e5436536SAndroid Build Coastguard Worker     case AOT_AAC_LC:
1206*e5436536SAndroid Build Coastguard Worker     case AOT_SBR:
1207*e5436536SAndroid Build Coastguard Worker     case AOT_PS:
1208*e5436536SAndroid Build Coastguard Worker     case AOT_MP2_AAC_LC:
1209*e5436536SAndroid Build Coastguard Worker     case AOT_MP2_SBR:
1210*e5436536SAndroid Build Coastguard Worker       hAacEncoder->metaDataAllowed = 1;
1211*e5436536SAndroid Build Coastguard Worker       if (!((((INT)hAacConfig->channelMode >= 1) &&
1212*e5436536SAndroid Build Coastguard Worker              ((INT)hAacConfig->channelMode <= 14)) ||
1213*e5436536SAndroid Build Coastguard Worker             (MODE_7_1_REAR_SURROUND == hAacConfig->channelMode) ||
1214*e5436536SAndroid Build Coastguard Worker             (MODE_7_1_FRONT_CENTER == hAacConfig->channelMode))) {
1215*e5436536SAndroid Build Coastguard Worker         config->userMetaDataMode = 0;
1216*e5436536SAndroid Build Coastguard Worker       }
1217*e5436536SAndroid Build Coastguard Worker       break;
1218*e5436536SAndroid Build Coastguard Worker     /* Prohibit metadata support */
1219*e5436536SAndroid Build Coastguard Worker     default:
1220*e5436536SAndroid Build Coastguard Worker       hAacEncoder->metaDataAllowed = 0;
1221*e5436536SAndroid Build Coastguard Worker   }
1222*e5436536SAndroid Build Coastguard Worker 
1223*e5436536SAndroid Build Coastguard Worker   return err;
1224*e5436536SAndroid Build Coastguard Worker }
1225*e5436536SAndroid Build Coastguard Worker 
aacenc_SbrCallback(void * self,HANDLE_FDK_BITSTREAM hBs,const INT sampleRateIn,const INT sampleRateOut,const INT samplesPerFrame,const AUDIO_OBJECT_TYPE coreCodec,const MP4_ELEMENT_ID elementID,const INT elementIndex,const UCHAR harmonicSbr,const UCHAR stereoConfigIndex,const UCHAR configMode,UCHAR * configChanged,const INT downscaleFactor)1226*e5436536SAndroid Build Coastguard Worker static INT aacenc_SbrCallback(void *self, HANDLE_FDK_BITSTREAM hBs,
1227*e5436536SAndroid Build Coastguard Worker                               const INT sampleRateIn, const INT sampleRateOut,
1228*e5436536SAndroid Build Coastguard Worker                               const INT samplesPerFrame,
1229*e5436536SAndroid Build Coastguard Worker                               const AUDIO_OBJECT_TYPE coreCodec,
1230*e5436536SAndroid Build Coastguard Worker                               const MP4_ELEMENT_ID elementID,
1231*e5436536SAndroid Build Coastguard Worker                               const INT elementIndex, const UCHAR harmonicSbr,
1232*e5436536SAndroid Build Coastguard Worker                               const UCHAR stereoConfigIndex,
1233*e5436536SAndroid Build Coastguard Worker                               const UCHAR configMode, UCHAR *configChanged,
1234*e5436536SAndroid Build Coastguard Worker                               const INT downscaleFactor) {
1235*e5436536SAndroid Build Coastguard Worker   HANDLE_AACENCODER hAacEncoder = (HANDLE_AACENCODER)self;
1236*e5436536SAndroid Build Coastguard Worker 
1237*e5436536SAndroid Build Coastguard Worker   sbrEncoder_GetHeader(hAacEncoder->hEnvEnc, hBs, elementIndex, 0);
1238*e5436536SAndroid Build Coastguard Worker 
1239*e5436536SAndroid Build Coastguard Worker   return 0;
1240*e5436536SAndroid Build Coastguard Worker }
1241*e5436536SAndroid Build Coastguard Worker 
aacenc_SscCallback(void * self,HANDLE_FDK_BITSTREAM hBs,const AUDIO_OBJECT_TYPE coreCodec,const INT samplingRate,const INT frameSize,const INT numChannels,const INT stereoConfigIndex,const INT coreSbrFrameLengthIndex,const INT configBytes,const UCHAR configMode,UCHAR * configChanged)1242*e5436536SAndroid Build Coastguard Worker INT aacenc_SscCallback(void *self, HANDLE_FDK_BITSTREAM hBs,
1243*e5436536SAndroid Build Coastguard Worker                        const AUDIO_OBJECT_TYPE coreCodec,
1244*e5436536SAndroid Build Coastguard Worker                        const INT samplingRate, const INT frameSize,
1245*e5436536SAndroid Build Coastguard Worker                        const INT numChannels, const INT stereoConfigIndex,
1246*e5436536SAndroid Build Coastguard Worker                        const INT coreSbrFrameLengthIndex, const INT configBytes,
1247*e5436536SAndroid Build Coastguard Worker                        const UCHAR configMode, UCHAR *configChanged) {
1248*e5436536SAndroid Build Coastguard Worker   HANDLE_AACENCODER hAacEncoder = (HANDLE_AACENCODER)self;
1249*e5436536SAndroid Build Coastguard Worker 
1250*e5436536SAndroid Build Coastguard Worker   return (FDK_MpegsEnc_WriteSpatialSpecificConfig(hAacEncoder->hMpsEnc, hBs));
1251*e5436536SAndroid Build Coastguard Worker }
1252*e5436536SAndroid Build Coastguard Worker 
aacEncInit(HANDLE_AACENCODER hAacEncoder,ULONG InitFlags,USER_PARAM * config)1253*e5436536SAndroid Build Coastguard Worker static AACENC_ERROR aacEncInit(HANDLE_AACENCODER hAacEncoder, ULONG InitFlags,
1254*e5436536SAndroid Build Coastguard Worker                                USER_PARAM *config) {
1255*e5436536SAndroid Build Coastguard Worker   AACENC_ERROR err = AACENC_OK;
1256*e5436536SAndroid Build Coastguard Worker 
1257*e5436536SAndroid Build Coastguard Worker   INT aacBufferOffset = 0;
1258*e5436536SAndroid Build Coastguard Worker   HANDLE_SBR_ENCODER *hSbrEncoder = &hAacEncoder->hEnvEnc;
1259*e5436536SAndroid Build Coastguard Worker   HANDLE_AACENC_CONFIG hAacConfig = &hAacEncoder->aacConfig;
1260*e5436536SAndroid Build Coastguard Worker 
1261*e5436536SAndroid Build Coastguard Worker   hAacEncoder->nZerosAppended = 0; /* count appended zeros */
1262*e5436536SAndroid Build Coastguard Worker 
1263*e5436536SAndroid Build Coastguard Worker   INT frameLength = hAacConfig->framelength;
1264*e5436536SAndroid Build Coastguard Worker 
1265*e5436536SAndroid Build Coastguard Worker   if ((InitFlags & AACENC_INIT_CONFIG)) {
1266*e5436536SAndroid Build Coastguard Worker     CHANNEL_MODE prevChMode = hAacConfig->channelMode;
1267*e5436536SAndroid Build Coastguard Worker 
1268*e5436536SAndroid Build Coastguard Worker     /* Verify settings and update: config -> heAacEncoder */
1269*e5436536SAndroid Build Coastguard Worker     if ((err = FDKaacEnc_AdjustEncSettings(hAacEncoder, config)) != AACENC_OK) {
1270*e5436536SAndroid Build Coastguard Worker       return err;
1271*e5436536SAndroid Build Coastguard Worker     }
1272*e5436536SAndroid Build Coastguard Worker     frameLength = hAacConfig->framelength; /* adapt temporal framelength */
1273*e5436536SAndroid Build Coastguard Worker 
1274*e5436536SAndroid Build Coastguard Worker     /* Seamless channel reconfiguration in sbr not fully implemented */
1275*e5436536SAndroid Build Coastguard Worker     if ((prevChMode != hAacConfig->channelMode) && isSbrActive(hAacConfig)) {
1276*e5436536SAndroid Build Coastguard Worker       InitFlags |= AACENC_INIT_STATES;
1277*e5436536SAndroid Build Coastguard Worker     }
1278*e5436536SAndroid Build Coastguard Worker   }
1279*e5436536SAndroid Build Coastguard Worker 
1280*e5436536SAndroid Build Coastguard Worker   /* Clear input buffer */
1281*e5436536SAndroid Build Coastguard Worker   if (InitFlags == AACENC_INIT_ALL) {
1282*e5436536SAndroid Build Coastguard Worker     FDKmemclear(hAacEncoder->inputBuffer,
1283*e5436536SAndroid Build Coastguard Worker                 sizeof(INT_PCM) * hAacEncoder->inputBufferSize);
1284*e5436536SAndroid Build Coastguard Worker   }
1285*e5436536SAndroid Build Coastguard Worker 
1286*e5436536SAndroid Build Coastguard Worker   if ((InitFlags & AACENC_INIT_CONFIG)) {
1287*e5436536SAndroid Build Coastguard Worker     aacBufferOffset = 0;
1288*e5436536SAndroid Build Coastguard Worker     switch (hAacConfig->audioObjectType) {
1289*e5436536SAndroid Build Coastguard Worker       case AOT_ER_AAC_LD:
1290*e5436536SAndroid Build Coastguard Worker         hAacEncoder->nDelay = DELAY_AACLD(hAacConfig->framelength);
1291*e5436536SAndroid Build Coastguard Worker         break;
1292*e5436536SAndroid Build Coastguard Worker       case AOT_ER_AAC_ELD:
1293*e5436536SAndroid Build Coastguard Worker         hAacEncoder->nDelay = DELAY_AACELD(hAacConfig->framelength);
1294*e5436536SAndroid Build Coastguard Worker         break;
1295*e5436536SAndroid Build Coastguard Worker       default:
1296*e5436536SAndroid Build Coastguard Worker         hAacEncoder->nDelay =
1297*e5436536SAndroid Build Coastguard Worker             DELAY_AAC(hAacConfig->framelength); /* AAC encoder delay */
1298*e5436536SAndroid Build Coastguard Worker     }
1299*e5436536SAndroid Build Coastguard Worker 
1300*e5436536SAndroid Build Coastguard Worker     hAacConfig->ancDataBitRate = 0;
1301*e5436536SAndroid Build Coastguard Worker   }
1302*e5436536SAndroid Build Coastguard Worker 
1303*e5436536SAndroid Build Coastguard Worker   if ((NULL != hAacEncoder->hEnvEnc) && isSbrActive(hAacConfig) &&
1304*e5436536SAndroid Build Coastguard Worker       ((InitFlags & AACENC_INIT_CONFIG) || (InitFlags & AACENC_INIT_STATES))) {
1305*e5436536SAndroid Build Coastguard Worker     INT sbrError;
1306*e5436536SAndroid Build Coastguard Worker     UINT initFlag = 0;
1307*e5436536SAndroid Build Coastguard Worker     SBR_ELEMENT_INFO sbrElInfo[(8)];
1308*e5436536SAndroid Build Coastguard Worker     CHANNEL_MAPPING channelMapping;
1309*e5436536SAndroid Build Coastguard Worker     CHANNEL_MODE channelMode = isPsActive(hAacConfig->audioObjectType)
1310*e5436536SAndroid Build Coastguard Worker                                    ? config->userChannelMode
1311*e5436536SAndroid Build Coastguard Worker                                    : hAacConfig->channelMode;
1312*e5436536SAndroid Build Coastguard Worker     INT numChannels = isPsActive(hAacConfig->audioObjectType)
1313*e5436536SAndroid Build Coastguard Worker                           ? config->nChannels
1314*e5436536SAndroid Build Coastguard Worker                           : hAacConfig->nChannels;
1315*e5436536SAndroid Build Coastguard Worker 
1316*e5436536SAndroid Build Coastguard Worker     if (FDKaacEnc_InitChannelMapping(channelMode, hAacConfig->channelOrder,
1317*e5436536SAndroid Build Coastguard Worker                                      &channelMapping) != AAC_ENC_OK) {
1318*e5436536SAndroid Build Coastguard Worker       return AACENC_INIT_ERROR;
1319*e5436536SAndroid Build Coastguard Worker     }
1320*e5436536SAndroid Build Coastguard Worker 
1321*e5436536SAndroid Build Coastguard Worker     /* Check return value and if the SBR encoder can handle enough elements */
1322*e5436536SAndroid Build Coastguard Worker     if (channelMapping.nElements > (8)) {
1323*e5436536SAndroid Build Coastguard Worker       return AACENC_INIT_ERROR;
1324*e5436536SAndroid Build Coastguard Worker     }
1325*e5436536SAndroid Build Coastguard Worker 
1326*e5436536SAndroid Build Coastguard Worker     aacEncDistributeSbrBits(&channelMapping, sbrElInfo, hAacConfig->bitRate);
1327*e5436536SAndroid Build Coastguard Worker 
1328*e5436536SAndroid Build Coastguard Worker     initFlag += (InitFlags & AACENC_INIT_STATES) ? 1 : 0;
1329*e5436536SAndroid Build Coastguard Worker 
1330*e5436536SAndroid Build Coastguard Worker     /* Let the SBR encoder take a look at the configuration and change if
1331*e5436536SAndroid Build Coastguard Worker      * required. */
1332*e5436536SAndroid Build Coastguard Worker     sbrError = sbrEncoder_Init(
1333*e5436536SAndroid Build Coastguard Worker         *hSbrEncoder, sbrElInfo, channelMapping.nElements,
1334*e5436536SAndroid Build Coastguard Worker         hAacEncoder->inputBuffer, hAacEncoder->inputBufferSizePerChannel,
1335*e5436536SAndroid Build Coastguard Worker         &hAacConfig->bandWidth, &aacBufferOffset, &numChannels,
1336*e5436536SAndroid Build Coastguard Worker         hAacConfig->syntaxFlags, &hAacConfig->sampleRate, &hAacConfig->sbrRatio,
1337*e5436536SAndroid Build Coastguard Worker         &frameLength, hAacConfig->audioObjectType, &hAacEncoder->nDelay,
1338*e5436536SAndroid Build Coastguard Worker         (hAacConfig->audioObjectType == AOT_ER_AAC_ELD) ? 1 : TRANS_FAC,
1339*e5436536SAndroid Build Coastguard Worker         (config->userTpHeaderPeriod != 0xFF)
1340*e5436536SAndroid Build Coastguard Worker             ? config->userTpHeaderPeriod
1341*e5436536SAndroid Build Coastguard Worker             : DEFAULT_HEADER_PERIOD_REPETITION_RATE,
1342*e5436536SAndroid Build Coastguard Worker         initFlag);
1343*e5436536SAndroid Build Coastguard Worker 
1344*e5436536SAndroid Build Coastguard Worker     /* Suppress AOT reconfiguration and check error status. */
1345*e5436536SAndroid Build Coastguard Worker     if ((sbrError) || (numChannels != hAacConfig->nChannels)) {
1346*e5436536SAndroid Build Coastguard Worker       return AACENC_INIT_SBR_ERROR;
1347*e5436536SAndroid Build Coastguard Worker     }
1348*e5436536SAndroid Build Coastguard Worker 
1349*e5436536SAndroid Build Coastguard Worker     if (numChannels == 1) {
1350*e5436536SAndroid Build Coastguard Worker       hAacConfig->channelMode = MODE_1;
1351*e5436536SAndroid Build Coastguard Worker     }
1352*e5436536SAndroid Build Coastguard Worker 
1353*e5436536SAndroid Build Coastguard Worker     /* Never use PNS if SBR is active */
1354*e5436536SAndroid Build Coastguard Worker     if (hAacConfig->usePns) {
1355*e5436536SAndroid Build Coastguard Worker       hAacConfig->usePns = 0;
1356*e5436536SAndroid Build Coastguard Worker     }
1357*e5436536SAndroid Build Coastguard Worker 
1358*e5436536SAndroid Build Coastguard Worker     /* estimated bitrate consumed by SBR or PS */
1359*e5436536SAndroid Build Coastguard Worker     hAacConfig->ancDataBitRate = sbrEncoder_GetEstimateBitrate(*hSbrEncoder);
1360*e5436536SAndroid Build Coastguard Worker 
1361*e5436536SAndroid Build Coastguard Worker   } /* sbr initialization */
1362*e5436536SAndroid Build Coastguard Worker 
1363*e5436536SAndroid Build Coastguard Worker   if ((hAacEncoder->hMpsEnc != NULL) && (hAacConfig->syntaxFlags & AC_LD_MPS)) {
1364*e5436536SAndroid Build Coastguard Worker     int coreCoderDelay = DELAY_AACELD(hAacConfig->framelength);
1365*e5436536SAndroid Build Coastguard Worker 
1366*e5436536SAndroid Build Coastguard Worker     if (isSbrActive(hAacConfig)) {
1367*e5436536SAndroid Build Coastguard Worker       coreCoderDelay = hAacConfig->sbrRatio * coreCoderDelay +
1368*e5436536SAndroid Build Coastguard Worker                        sbrEncoder_GetInputDataDelay(*hSbrEncoder);
1369*e5436536SAndroid Build Coastguard Worker     }
1370*e5436536SAndroid Build Coastguard Worker 
1371*e5436536SAndroid Build Coastguard Worker     if (MPS_ENCODER_OK !=
1372*e5436536SAndroid Build Coastguard Worker         FDK_MpegsEnc_Init(hAacEncoder->hMpsEnc, hAacConfig->audioObjectType,
1373*e5436536SAndroid Build Coastguard Worker                           config->userSamplerate, hAacConfig->bitRate,
1374*e5436536SAndroid Build Coastguard Worker                           isSbrActive(hAacConfig) ? hAacConfig->sbrRatio : 0,
1375*e5436536SAndroid Build Coastguard Worker                           frameLength, /* for dual rate sbr this value is
1376*e5436536SAndroid Build Coastguard Worker                                           already multiplied by 2 */
1377*e5436536SAndroid Build Coastguard Worker                           hAacEncoder->inputBufferSizePerChannel,
1378*e5436536SAndroid Build Coastguard Worker                           coreCoderDelay)) {
1379*e5436536SAndroid Build Coastguard Worker       return AACENC_INIT_MPS_ERROR;
1380*e5436536SAndroid Build Coastguard Worker     }
1381*e5436536SAndroid Build Coastguard Worker   }
1382*e5436536SAndroid Build Coastguard Worker   hAacEncoder->nDelay =
1383*e5436536SAndroid Build Coastguard Worker       fMax(FDK_MpegsEnc_GetDelay(hAacEncoder->hMpsEnc), hAacEncoder->nDelay);
1384*e5436536SAndroid Build Coastguard Worker 
1385*e5436536SAndroid Build Coastguard Worker   /*
1386*e5436536SAndroid Build Coastguard Worker    * Initialize Transport - Module.
1387*e5436536SAndroid Build Coastguard Worker    */
1388*e5436536SAndroid Build Coastguard Worker   if ((InitFlags & AACENC_INIT_TRANSPORT)) {
1389*e5436536SAndroid Build Coastguard Worker     UINT flags = 0;
1390*e5436536SAndroid Build Coastguard Worker 
1391*e5436536SAndroid Build Coastguard Worker     FDKaacEnc_MapConfig(
1392*e5436536SAndroid Build Coastguard Worker         &hAacEncoder->coderConfig, config,
1393*e5436536SAndroid Build Coastguard Worker         getSbrSignalingMode(hAacConfig->audioObjectType, config->userTpType,
1394*e5436536SAndroid Build Coastguard Worker                             config->userTpSignaling, hAacConfig->sbrRatio),
1395*e5436536SAndroid Build Coastguard Worker         hAacConfig);
1396*e5436536SAndroid Build Coastguard Worker 
1397*e5436536SAndroid Build Coastguard Worker     /* create flags for transport encoder */
1398*e5436536SAndroid Build Coastguard Worker     if (config->userTpAmxv != 0) {
1399*e5436536SAndroid Build Coastguard Worker       flags |= TP_FLAG_LATM_AMV;
1400*e5436536SAndroid Build Coastguard Worker     }
1401*e5436536SAndroid Build Coastguard Worker     /* Clear output buffer */
1402*e5436536SAndroid Build Coastguard Worker     FDKmemclear(hAacEncoder->outBuffer,
1403*e5436536SAndroid Build Coastguard Worker                 hAacEncoder->outBufferInBytes * sizeof(UCHAR));
1404*e5436536SAndroid Build Coastguard Worker 
1405*e5436536SAndroid Build Coastguard Worker     /* Initialize Bitstream encoder */
1406*e5436536SAndroid Build Coastguard Worker     if (transportEnc_Init(hAacEncoder->hTpEnc, hAacEncoder->outBuffer,
1407*e5436536SAndroid Build Coastguard Worker                           hAacEncoder->outBufferInBytes, config->userTpType,
1408*e5436536SAndroid Build Coastguard Worker                           &hAacEncoder->coderConfig, flags) != 0) {
1409*e5436536SAndroid Build Coastguard Worker       return AACENC_INIT_TP_ERROR;
1410*e5436536SAndroid Build Coastguard Worker     }
1411*e5436536SAndroid Build Coastguard Worker 
1412*e5436536SAndroid Build Coastguard Worker   } /* transport initialization */
1413*e5436536SAndroid Build Coastguard Worker 
1414*e5436536SAndroid Build Coastguard Worker   /*
1415*e5436536SAndroid Build Coastguard Worker    * Initialize AAC - Core.
1416*e5436536SAndroid Build Coastguard Worker    */
1417*e5436536SAndroid Build Coastguard Worker   if ((InitFlags & AACENC_INIT_CONFIG) || (InitFlags & AACENC_INIT_STATES)) {
1418*e5436536SAndroid Build Coastguard Worker     if (FDKaacEnc_Initialize(
1419*e5436536SAndroid Build Coastguard Worker             hAacEncoder->hAacEnc, hAacConfig, hAacEncoder->hTpEnc,
1420*e5436536SAndroid Build Coastguard Worker             (InitFlags & AACENC_INIT_STATES) ? 1 : 0) != AAC_ENC_OK) {
1421*e5436536SAndroid Build Coastguard Worker       return AACENC_INIT_AAC_ERROR;
1422*e5436536SAndroid Build Coastguard Worker     }
1423*e5436536SAndroid Build Coastguard Worker 
1424*e5436536SAndroid Build Coastguard Worker   } /* aac initialization */
1425*e5436536SAndroid Build Coastguard Worker 
1426*e5436536SAndroid Build Coastguard Worker   /*
1427*e5436536SAndroid Build Coastguard Worker    * Initialize Meta Data - Encoder.
1428*e5436536SAndroid Build Coastguard Worker    */
1429*e5436536SAndroid Build Coastguard Worker   if (hAacEncoder->hMetadataEnc && (hAacEncoder->metaDataAllowed != 0) &&
1430*e5436536SAndroid Build Coastguard Worker       ((InitFlags & AACENC_INIT_CONFIG) || (InitFlags & AACENC_INIT_STATES))) {
1431*e5436536SAndroid Build Coastguard Worker     INT inputDataDelay = DELAY_AAC(hAacConfig->framelength);
1432*e5436536SAndroid Build Coastguard Worker 
1433*e5436536SAndroid Build Coastguard Worker     if (isSbrActive(hAacConfig) && hSbrEncoder != NULL) {
1434*e5436536SAndroid Build Coastguard Worker       inputDataDelay = hAacConfig->sbrRatio * inputDataDelay +
1435*e5436536SAndroid Build Coastguard Worker                        sbrEncoder_GetInputDataDelay(*hSbrEncoder);
1436*e5436536SAndroid Build Coastguard Worker     }
1437*e5436536SAndroid Build Coastguard Worker 
1438*e5436536SAndroid Build Coastguard Worker     if (FDK_MetadataEnc_Init(hAacEncoder->hMetadataEnc,
1439*e5436536SAndroid Build Coastguard Worker                              ((InitFlags & AACENC_INIT_STATES) ? 1 : 0),
1440*e5436536SAndroid Build Coastguard Worker                              config->userMetaDataMode, inputDataDelay,
1441*e5436536SAndroid Build Coastguard Worker                              frameLength, config->userSamplerate,
1442*e5436536SAndroid Build Coastguard Worker                              config->nChannels, config->userChannelMode,
1443*e5436536SAndroid Build Coastguard Worker                              hAacConfig->channelOrder) != 0) {
1444*e5436536SAndroid Build Coastguard Worker       return AACENC_INIT_META_ERROR;
1445*e5436536SAndroid Build Coastguard Worker     }
1446*e5436536SAndroid Build Coastguard Worker 
1447*e5436536SAndroid Build Coastguard Worker     hAacEncoder->nDelay += FDK_MetadataEnc_GetDelay(hAacEncoder->hMetadataEnc);
1448*e5436536SAndroid Build Coastguard Worker   }
1449*e5436536SAndroid Build Coastguard Worker 
1450*e5436536SAndroid Build Coastguard Worker   /* Get custom delay, i.e. the codec delay w/o the decoder's SBR- or MPS delay
1451*e5436536SAndroid Build Coastguard Worker    */
1452*e5436536SAndroid Build Coastguard Worker   if ((hAacEncoder->hMpsEnc != NULL) && (hAacConfig->syntaxFlags & AC_LD_MPS)) {
1453*e5436536SAndroid Build Coastguard Worker     hAacEncoder->nDelayCore =
1454*e5436536SAndroid Build Coastguard Worker         hAacEncoder->nDelay -
1455*e5436536SAndroid Build Coastguard Worker         fMax(0, FDK_MpegsEnc_GetDecDelay(hAacEncoder->hMpsEnc));
1456*e5436536SAndroid Build Coastguard Worker   } else if (isSbrActive(hAacConfig) && hSbrEncoder != NULL) {
1457*e5436536SAndroid Build Coastguard Worker     hAacEncoder->nDelayCore =
1458*e5436536SAndroid Build Coastguard Worker         hAacEncoder->nDelay -
1459*e5436536SAndroid Build Coastguard Worker         fMax(0, sbrEncoder_GetSbrDecDelay(hAacEncoder->hEnvEnc));
1460*e5436536SAndroid Build Coastguard Worker   } else {
1461*e5436536SAndroid Build Coastguard Worker     hAacEncoder->nDelayCore = hAacEncoder->nDelay;
1462*e5436536SAndroid Build Coastguard Worker   }
1463*e5436536SAndroid Build Coastguard Worker 
1464*e5436536SAndroid Build Coastguard Worker   /*
1465*e5436536SAndroid Build Coastguard Worker    * Update pointer to working buffer.
1466*e5436536SAndroid Build Coastguard Worker    */
1467*e5436536SAndroid Build Coastguard Worker   if ((InitFlags & AACENC_INIT_CONFIG)) {
1468*e5436536SAndroid Build Coastguard Worker     hAacEncoder->inputBufferOffset = aacBufferOffset;
1469*e5436536SAndroid Build Coastguard Worker 
1470*e5436536SAndroid Build Coastguard Worker     hAacEncoder->nSamplesToRead = frameLength * config->nChannels;
1471*e5436536SAndroid Build Coastguard Worker 
1472*e5436536SAndroid Build Coastguard Worker   } /* parameter changed */
1473*e5436536SAndroid Build Coastguard Worker 
1474*e5436536SAndroid Build Coastguard Worker   return AACENC_OK;
1475*e5436536SAndroid Build Coastguard Worker }
1476*e5436536SAndroid Build Coastguard Worker 
aacEncOpen(HANDLE_AACENCODER * phAacEncoder,const UINT encModules,const UINT maxChannels)1477*e5436536SAndroid Build Coastguard Worker AACENC_ERROR aacEncOpen(HANDLE_AACENCODER *phAacEncoder, const UINT encModules,
1478*e5436536SAndroid Build Coastguard Worker                         const UINT maxChannels) {
1479*e5436536SAndroid Build Coastguard Worker   AACENC_ERROR err = AACENC_OK;
1480*e5436536SAndroid Build Coastguard Worker   HANDLE_AACENCODER hAacEncoder = NULL;
1481*e5436536SAndroid Build Coastguard Worker 
1482*e5436536SAndroid Build Coastguard Worker   if (phAacEncoder == NULL) {
1483*e5436536SAndroid Build Coastguard Worker     err = AACENC_INVALID_HANDLE;
1484*e5436536SAndroid Build Coastguard Worker     goto bail;
1485*e5436536SAndroid Build Coastguard Worker   }
1486*e5436536SAndroid Build Coastguard Worker 
1487*e5436536SAndroid Build Coastguard Worker   /* allocate memory */
1488*e5436536SAndroid Build Coastguard Worker   hAacEncoder = Get_AacEncoder();
1489*e5436536SAndroid Build Coastguard Worker 
1490*e5436536SAndroid Build Coastguard Worker   if (hAacEncoder == NULL) {
1491*e5436536SAndroid Build Coastguard Worker     err = AACENC_MEMORY_ERROR;
1492*e5436536SAndroid Build Coastguard Worker     goto bail;
1493*e5436536SAndroid Build Coastguard Worker   }
1494*e5436536SAndroid Build Coastguard Worker 
1495*e5436536SAndroid Build Coastguard Worker   FDKmemclear(hAacEncoder, sizeof(AACENCODER));
1496*e5436536SAndroid Build Coastguard Worker 
1497*e5436536SAndroid Build Coastguard Worker   /* Specify encoder modules to be allocated. */
1498*e5436536SAndroid Build Coastguard Worker   if (encModules == 0) {
1499*e5436536SAndroid Build Coastguard Worker     C_ALLOC_SCRATCH_START(_pLibInfo, LIB_INFO, FDK_MODULE_LAST)
1500*e5436536SAndroid Build Coastguard Worker     LIB_INFO(*pLibInfo)
1501*e5436536SAndroid Build Coastguard Worker     [FDK_MODULE_LAST] = (LIB_INFO(*)[FDK_MODULE_LAST])_pLibInfo;
1502*e5436536SAndroid Build Coastguard Worker     FDKinitLibInfo(*pLibInfo);
1503*e5436536SAndroid Build Coastguard Worker     aacEncGetLibInfo(*pLibInfo);
1504*e5436536SAndroid Build Coastguard Worker 
1505*e5436536SAndroid Build Coastguard Worker     hAacEncoder->encoder_modis = ENC_MODE_FLAG_AAC;
1506*e5436536SAndroid Build Coastguard Worker     if (FDKlibInfo_getCapabilities(*pLibInfo, FDK_SBRENC) & CAPF_SBR_HQ) {
1507*e5436536SAndroid Build Coastguard Worker       hAacEncoder->encoder_modis |= ENC_MODE_FLAG_SBR;
1508*e5436536SAndroid Build Coastguard Worker     }
1509*e5436536SAndroid Build Coastguard Worker     if (FDKlibInfo_getCapabilities(*pLibInfo, FDK_SBRENC) & CAPF_SBR_PS_MPEG) {
1510*e5436536SAndroid Build Coastguard Worker       hAacEncoder->encoder_modis |= ENC_MODE_FLAG_PS;
1511*e5436536SAndroid Build Coastguard Worker     }
1512*e5436536SAndroid Build Coastguard Worker     if (FDKlibInfo_getCapabilities(*pLibInfo, FDK_AACENC) & CAPF_AAC_DRC) {
1513*e5436536SAndroid Build Coastguard Worker       hAacEncoder->encoder_modis |= ENC_MODE_FLAG_META;
1514*e5436536SAndroid Build Coastguard Worker     }
1515*e5436536SAndroid Build Coastguard Worker     hAacEncoder->encoder_modis |= ENC_MODE_FLAG_SAC;
1516*e5436536SAndroid Build Coastguard Worker 
1517*e5436536SAndroid Build Coastguard Worker     C_ALLOC_SCRATCH_END(_pLibInfo, LIB_INFO, FDK_MODULE_LAST)
1518*e5436536SAndroid Build Coastguard Worker   } else {
1519*e5436536SAndroid Build Coastguard Worker     hAacEncoder->encoder_modis = encModules;
1520*e5436536SAndroid Build Coastguard Worker   }
1521*e5436536SAndroid Build Coastguard Worker 
1522*e5436536SAndroid Build Coastguard Worker   /* Determine max channel configuration. */
1523*e5436536SAndroid Build Coastguard Worker   if (maxChannels == 0) {
1524*e5436536SAndroid Build Coastguard Worker     hAacEncoder->nMaxAacChannels = (8);
1525*e5436536SAndroid Build Coastguard Worker     hAacEncoder->nMaxSbrChannels = (8);
1526*e5436536SAndroid Build Coastguard Worker   } else {
1527*e5436536SAndroid Build Coastguard Worker     hAacEncoder->nMaxAacChannels = (maxChannels & 0x00FF);
1528*e5436536SAndroid Build Coastguard Worker     if ((hAacEncoder->encoder_modis & ENC_MODE_FLAG_SBR)) {
1529*e5436536SAndroid Build Coastguard Worker       hAacEncoder->nMaxSbrChannels = (maxChannels & 0xFF00)
1530*e5436536SAndroid Build Coastguard Worker                                          ? (maxChannels >> 8)
1531*e5436536SAndroid Build Coastguard Worker                                          : hAacEncoder->nMaxAacChannels;
1532*e5436536SAndroid Build Coastguard Worker     }
1533*e5436536SAndroid Build Coastguard Worker 
1534*e5436536SAndroid Build Coastguard Worker     if ((hAacEncoder->nMaxAacChannels > (8)) ||
1535*e5436536SAndroid Build Coastguard Worker         (hAacEncoder->nMaxSbrChannels > (8))) {
1536*e5436536SAndroid Build Coastguard Worker       err = AACENC_INVALID_CONFIG;
1537*e5436536SAndroid Build Coastguard Worker       goto bail;
1538*e5436536SAndroid Build Coastguard Worker     }
1539*e5436536SAndroid Build Coastguard Worker   } /* maxChannels==0 */
1540*e5436536SAndroid Build Coastguard Worker 
1541*e5436536SAndroid Build Coastguard Worker   /* Max number of elements could be tuned any more. */
1542*e5436536SAndroid Build Coastguard Worker   hAacEncoder->nMaxAacElements = fixMin(((8)), hAacEncoder->nMaxAacChannels);
1543*e5436536SAndroid Build Coastguard Worker   hAacEncoder->nMaxSbrElements = fixMin((8), hAacEncoder->nMaxSbrChannels);
1544*e5436536SAndroid Build Coastguard Worker 
1545*e5436536SAndroid Build Coastguard Worker   /* In case of memory overlay, allocate memory out of libraries */
1546*e5436536SAndroid Build Coastguard Worker 
1547*e5436536SAndroid Build Coastguard Worker   if (hAacEncoder->encoder_modis & (ENC_MODE_FLAG_SBR | ENC_MODE_FLAG_PS))
1548*e5436536SAndroid Build Coastguard Worker     hAacEncoder->inputBufferSizePerChannel = INPUTBUFFER_SIZE;
1549*e5436536SAndroid Build Coastguard Worker   else
1550*e5436536SAndroid Build Coastguard Worker     hAacEncoder->inputBufferSizePerChannel = (1024);
1551*e5436536SAndroid Build Coastguard Worker 
1552*e5436536SAndroid Build Coastguard Worker   hAacEncoder->inputBufferSize =
1553*e5436536SAndroid Build Coastguard Worker       hAacEncoder->nMaxAacChannels * hAacEncoder->inputBufferSizePerChannel;
1554*e5436536SAndroid Build Coastguard Worker 
1555*e5436536SAndroid Build Coastguard Worker   if (NULL == (hAacEncoder->inputBuffer = (INT_PCM *)FDKcalloc(
1556*e5436536SAndroid Build Coastguard Worker                    hAacEncoder->inputBufferSize, sizeof(INT_PCM)))) {
1557*e5436536SAndroid Build Coastguard Worker     err = AACENC_MEMORY_ERROR;
1558*e5436536SAndroid Build Coastguard Worker     goto bail;
1559*e5436536SAndroid Build Coastguard Worker   }
1560*e5436536SAndroid Build Coastguard Worker 
1561*e5436536SAndroid Build Coastguard Worker   /* Open SBR Encoder */
1562*e5436536SAndroid Build Coastguard Worker   if (hAacEncoder->encoder_modis & ENC_MODE_FLAG_SBR) {
1563*e5436536SAndroid Build Coastguard Worker     if (sbrEncoder_Open(
1564*e5436536SAndroid Build Coastguard Worker             &hAacEncoder->hEnvEnc, hAacEncoder->nMaxSbrElements,
1565*e5436536SAndroid Build Coastguard Worker             hAacEncoder->nMaxSbrChannels,
1566*e5436536SAndroid Build Coastguard Worker             (hAacEncoder->encoder_modis & ENC_MODE_FLAG_PS) ? 1 : 0)) {
1567*e5436536SAndroid Build Coastguard Worker       err = AACENC_MEMORY_ERROR;
1568*e5436536SAndroid Build Coastguard Worker       goto bail;
1569*e5436536SAndroid Build Coastguard Worker     }
1570*e5436536SAndroid Build Coastguard Worker 
1571*e5436536SAndroid Build Coastguard Worker     if (NULL == (hAacEncoder->pSbrPayload = (SBRENC_EXT_PAYLOAD *)FDKcalloc(
1572*e5436536SAndroid Build Coastguard Worker                      1, sizeof(SBRENC_EXT_PAYLOAD)))) {
1573*e5436536SAndroid Build Coastguard Worker       err = AACENC_MEMORY_ERROR;
1574*e5436536SAndroid Build Coastguard Worker       goto bail;
1575*e5436536SAndroid Build Coastguard Worker     }
1576*e5436536SAndroid Build Coastguard Worker   } /* (encoder_modis&ENC_MODE_FLAG_SBR) */
1577*e5436536SAndroid Build Coastguard Worker 
1578*e5436536SAndroid Build Coastguard Worker   /* Open Aac Encoder */
1579*e5436536SAndroid Build Coastguard Worker   if (FDKaacEnc_Open(&hAacEncoder->hAacEnc, hAacEncoder->nMaxAacElements,
1580*e5436536SAndroid Build Coastguard Worker                      hAacEncoder->nMaxAacChannels, (1)) != AAC_ENC_OK) {
1581*e5436536SAndroid Build Coastguard Worker     err = AACENC_MEMORY_ERROR;
1582*e5436536SAndroid Build Coastguard Worker     goto bail;
1583*e5436536SAndroid Build Coastguard Worker   }
1584*e5436536SAndroid Build Coastguard Worker 
1585*e5436536SAndroid Build Coastguard Worker   /* Bitstream output buffer */
1586*e5436536SAndroid Build Coastguard Worker   hAacEncoder->outBufferInBytes =
1587*e5436536SAndroid Build Coastguard Worker       1 << (DFRACT_BITS - CntLeadingZeros(fixMax(
1588*e5436536SAndroid Build Coastguard Worker                               1, ((1) * hAacEncoder->nMaxAacChannels * 6144) >>
1589*e5436536SAndroid Build Coastguard Worker                                      3))); /* buffer has to be 2^n */
1590*e5436536SAndroid Build Coastguard Worker   if (NULL == (hAacEncoder->outBuffer = (UCHAR *)FDKcalloc(
1591*e5436536SAndroid Build Coastguard Worker                    hAacEncoder->outBufferInBytes, sizeof(UCHAR)))) {
1592*e5436536SAndroid Build Coastguard Worker     err = AACENC_MEMORY_ERROR;
1593*e5436536SAndroid Build Coastguard Worker     goto bail;
1594*e5436536SAndroid Build Coastguard Worker   }
1595*e5436536SAndroid Build Coastguard Worker 
1596*e5436536SAndroid Build Coastguard Worker   /* Open Meta Data Encoder */
1597*e5436536SAndroid Build Coastguard Worker   if (hAacEncoder->encoder_modis & ENC_MODE_FLAG_META) {
1598*e5436536SAndroid Build Coastguard Worker     if (FDK_MetadataEnc_Open(&hAacEncoder->hMetadataEnc,
1599*e5436536SAndroid Build Coastguard Worker                              (UINT)hAacEncoder->nMaxAacChannels)) {
1600*e5436536SAndroid Build Coastguard Worker       err = AACENC_MEMORY_ERROR;
1601*e5436536SAndroid Build Coastguard Worker       goto bail;
1602*e5436536SAndroid Build Coastguard Worker     }
1603*e5436536SAndroid Build Coastguard Worker   } /* (encoder_modis&ENC_MODE_FLAG_META) */
1604*e5436536SAndroid Build Coastguard Worker 
1605*e5436536SAndroid Build Coastguard Worker   /* Open MPEG Surround Encoder */
1606*e5436536SAndroid Build Coastguard Worker   if (hAacEncoder->encoder_modis & ENC_MODE_FLAG_SAC) {
1607*e5436536SAndroid Build Coastguard Worker     if (MPS_ENCODER_OK != FDK_MpegsEnc_Open(&hAacEncoder->hMpsEnc)) {
1608*e5436536SAndroid Build Coastguard Worker       err = AACENC_MEMORY_ERROR;
1609*e5436536SAndroid Build Coastguard Worker       goto bail;
1610*e5436536SAndroid Build Coastguard Worker     }
1611*e5436536SAndroid Build Coastguard Worker   } /* (hAacEncoder->encoder_modis&ENC_MODE_FLAG_SAC) */
1612*e5436536SAndroid Build Coastguard Worker 
1613*e5436536SAndroid Build Coastguard Worker   /* Open Transport Encoder */
1614*e5436536SAndroid Build Coastguard Worker   if (transportEnc_Open(&hAacEncoder->hTpEnc) != 0) {
1615*e5436536SAndroid Build Coastguard Worker     err = AACENC_MEMORY_ERROR;
1616*e5436536SAndroid Build Coastguard Worker     goto bail;
1617*e5436536SAndroid Build Coastguard Worker   } else {
1618*e5436536SAndroid Build Coastguard Worker     C_ALLOC_SCRATCH_START(_pLibInfo, LIB_INFO, FDK_MODULE_LAST)
1619*e5436536SAndroid Build Coastguard Worker 
1620*e5436536SAndroid Build Coastguard Worker     LIB_INFO(*pLibInfo)
1621*e5436536SAndroid Build Coastguard Worker     [FDK_MODULE_LAST] = (LIB_INFO(*)[FDK_MODULE_LAST])_pLibInfo;
1622*e5436536SAndroid Build Coastguard Worker 
1623*e5436536SAndroid Build Coastguard Worker     FDKinitLibInfo(*pLibInfo);
1624*e5436536SAndroid Build Coastguard Worker     transportEnc_GetLibInfo(*pLibInfo);
1625*e5436536SAndroid Build Coastguard Worker 
1626*e5436536SAndroid Build Coastguard Worker     /* Get capabilty flag for transport encoder. */
1627*e5436536SAndroid Build Coastguard Worker     hAacEncoder->CAPF_tpEnc = FDKlibInfo_getCapabilities(*pLibInfo, FDK_TPENC);
1628*e5436536SAndroid Build Coastguard Worker 
1629*e5436536SAndroid Build Coastguard Worker     C_ALLOC_SCRATCH_END(_pLibInfo, LIB_INFO, FDK_MODULE_LAST)
1630*e5436536SAndroid Build Coastguard Worker   }
1631*e5436536SAndroid Build Coastguard Worker   if (transportEnc_RegisterSbrCallback(hAacEncoder->hTpEnc, aacenc_SbrCallback,
1632*e5436536SAndroid Build Coastguard Worker                                        hAacEncoder) != 0) {
1633*e5436536SAndroid Build Coastguard Worker     err = AACENC_INIT_TP_ERROR;
1634*e5436536SAndroid Build Coastguard Worker     goto bail;
1635*e5436536SAndroid Build Coastguard Worker   }
1636*e5436536SAndroid Build Coastguard Worker   if (transportEnc_RegisterSscCallback(hAacEncoder->hTpEnc, aacenc_SscCallback,
1637*e5436536SAndroid Build Coastguard Worker                                        hAacEncoder) != 0) {
1638*e5436536SAndroid Build Coastguard Worker     err = AACENC_INIT_TP_ERROR;
1639*e5436536SAndroid Build Coastguard Worker     goto bail;
1640*e5436536SAndroid Build Coastguard Worker   }
1641*e5436536SAndroid Build Coastguard Worker 
1642*e5436536SAndroid Build Coastguard Worker   /* Initialize encoder instance with default parameters. */
1643*e5436536SAndroid Build Coastguard Worker   aacEncDefaultConfig(&hAacEncoder->aacConfig, &hAacEncoder->extParam);
1644*e5436536SAndroid Build Coastguard Worker 
1645*e5436536SAndroid Build Coastguard Worker   /* Initialize headerPeriod in coderConfig for aacEncoder_GetParam(). */
1646*e5436536SAndroid Build Coastguard Worker   hAacEncoder->coderConfig.headerPeriod =
1647*e5436536SAndroid Build Coastguard Worker       hAacEncoder->extParam.userTpHeaderPeriod;
1648*e5436536SAndroid Build Coastguard Worker 
1649*e5436536SAndroid Build Coastguard Worker   /* All encoder modules have to be initialized */
1650*e5436536SAndroid Build Coastguard Worker   hAacEncoder->InitFlags = AACENC_INIT_ALL;
1651*e5436536SAndroid Build Coastguard Worker 
1652*e5436536SAndroid Build Coastguard Worker   /* Return encoder instance */
1653*e5436536SAndroid Build Coastguard Worker   *phAacEncoder = hAacEncoder;
1654*e5436536SAndroid Build Coastguard Worker 
1655*e5436536SAndroid Build Coastguard Worker   return err;
1656*e5436536SAndroid Build Coastguard Worker 
1657*e5436536SAndroid Build Coastguard Worker bail:
1658*e5436536SAndroid Build Coastguard Worker   aacEncClose(&hAacEncoder);
1659*e5436536SAndroid Build Coastguard Worker 
1660*e5436536SAndroid Build Coastguard Worker   return err;
1661*e5436536SAndroid Build Coastguard Worker }
1662*e5436536SAndroid Build Coastguard Worker 
aacEncClose(HANDLE_AACENCODER * phAacEncoder)1663*e5436536SAndroid Build Coastguard Worker AACENC_ERROR aacEncClose(HANDLE_AACENCODER *phAacEncoder) {
1664*e5436536SAndroid Build Coastguard Worker   AACENC_ERROR err = AACENC_OK;
1665*e5436536SAndroid Build Coastguard Worker 
1666*e5436536SAndroid Build Coastguard Worker   if (phAacEncoder == NULL) {
1667*e5436536SAndroid Build Coastguard Worker     err = AACENC_INVALID_HANDLE;
1668*e5436536SAndroid Build Coastguard Worker     goto bail;
1669*e5436536SAndroid Build Coastguard Worker   }
1670*e5436536SAndroid Build Coastguard Worker 
1671*e5436536SAndroid Build Coastguard Worker   if (*phAacEncoder != NULL) {
1672*e5436536SAndroid Build Coastguard Worker     HANDLE_AACENCODER hAacEncoder = *phAacEncoder;
1673*e5436536SAndroid Build Coastguard Worker 
1674*e5436536SAndroid Build Coastguard Worker     if (hAacEncoder->inputBuffer != NULL) {
1675*e5436536SAndroid Build Coastguard Worker       FDKfree(hAacEncoder->inputBuffer);
1676*e5436536SAndroid Build Coastguard Worker       hAacEncoder->inputBuffer = NULL;
1677*e5436536SAndroid Build Coastguard Worker     }
1678*e5436536SAndroid Build Coastguard Worker     if (hAacEncoder->outBuffer != NULL) {
1679*e5436536SAndroid Build Coastguard Worker       FDKfree(hAacEncoder->outBuffer);
1680*e5436536SAndroid Build Coastguard Worker       hAacEncoder->outBuffer = NULL;
1681*e5436536SAndroid Build Coastguard Worker     }
1682*e5436536SAndroid Build Coastguard Worker 
1683*e5436536SAndroid Build Coastguard Worker     if (hAacEncoder->hEnvEnc) {
1684*e5436536SAndroid Build Coastguard Worker       sbrEncoder_Close(&hAacEncoder->hEnvEnc);
1685*e5436536SAndroid Build Coastguard Worker     }
1686*e5436536SAndroid Build Coastguard Worker     if (hAacEncoder->pSbrPayload != NULL) {
1687*e5436536SAndroid Build Coastguard Worker       FDKfree(hAacEncoder->pSbrPayload);
1688*e5436536SAndroid Build Coastguard Worker       hAacEncoder->pSbrPayload = NULL;
1689*e5436536SAndroid Build Coastguard Worker     }
1690*e5436536SAndroid Build Coastguard Worker     if (hAacEncoder->hAacEnc) {
1691*e5436536SAndroid Build Coastguard Worker       FDKaacEnc_Close(&hAacEncoder->hAacEnc);
1692*e5436536SAndroid Build Coastguard Worker     }
1693*e5436536SAndroid Build Coastguard Worker 
1694*e5436536SAndroid Build Coastguard Worker     transportEnc_Close(&hAacEncoder->hTpEnc);
1695*e5436536SAndroid Build Coastguard Worker 
1696*e5436536SAndroid Build Coastguard Worker     if (hAacEncoder->hMetadataEnc) {
1697*e5436536SAndroid Build Coastguard Worker       FDK_MetadataEnc_Close(&hAacEncoder->hMetadataEnc);
1698*e5436536SAndroid Build Coastguard Worker     }
1699*e5436536SAndroid Build Coastguard Worker     if (hAacEncoder->hMpsEnc) {
1700*e5436536SAndroid Build Coastguard Worker       FDK_MpegsEnc_Close(&hAacEncoder->hMpsEnc);
1701*e5436536SAndroid Build Coastguard Worker     }
1702*e5436536SAndroid Build Coastguard Worker 
1703*e5436536SAndroid Build Coastguard Worker     Free_AacEncoder(phAacEncoder);
1704*e5436536SAndroid Build Coastguard Worker   }
1705*e5436536SAndroid Build Coastguard Worker 
1706*e5436536SAndroid Build Coastguard Worker bail:
1707*e5436536SAndroid Build Coastguard Worker   return err;
1708*e5436536SAndroid Build Coastguard Worker }
1709*e5436536SAndroid Build Coastguard Worker 
aacEncEncode(const HANDLE_AACENCODER hAacEncoder,const AACENC_BufDesc * inBufDesc,const AACENC_BufDesc * outBufDesc,const AACENC_InArgs * inargs,AACENC_OutArgs * outargs)1710*e5436536SAndroid Build Coastguard Worker AACENC_ERROR aacEncEncode(const HANDLE_AACENCODER hAacEncoder,
1711*e5436536SAndroid Build Coastguard Worker                           const AACENC_BufDesc *inBufDesc,
1712*e5436536SAndroid Build Coastguard Worker                           const AACENC_BufDesc *outBufDesc,
1713*e5436536SAndroid Build Coastguard Worker                           const AACENC_InArgs *inargs,
1714*e5436536SAndroid Build Coastguard Worker                           AACENC_OutArgs *outargs) {
1715*e5436536SAndroid Build Coastguard Worker   AACENC_ERROR err = AACENC_OK;
1716*e5436536SAndroid Build Coastguard Worker   INT i, nBsBytes = 0;
1717*e5436536SAndroid Build Coastguard Worker   INT outBytes[(1)];
1718*e5436536SAndroid Build Coastguard Worker   int nExtensions = 0;
1719*e5436536SAndroid Build Coastguard Worker   int ancDataExtIdx = -1;
1720*e5436536SAndroid Build Coastguard Worker 
1721*e5436536SAndroid Build Coastguard Worker   /* deal with valid encoder handle */
1722*e5436536SAndroid Build Coastguard Worker   if (hAacEncoder == NULL) {
1723*e5436536SAndroid Build Coastguard Worker     err = AACENC_INVALID_HANDLE;
1724*e5436536SAndroid Build Coastguard Worker     goto bail;
1725*e5436536SAndroid Build Coastguard Worker   }
1726*e5436536SAndroid Build Coastguard Worker 
1727*e5436536SAndroid Build Coastguard Worker   /*
1728*e5436536SAndroid Build Coastguard Worker    * Adjust user settings and trigger reinitialization.
1729*e5436536SAndroid Build Coastguard Worker    */
1730*e5436536SAndroid Build Coastguard Worker   if (hAacEncoder->InitFlags != 0) {
1731*e5436536SAndroid Build Coastguard Worker     err =
1732*e5436536SAndroid Build Coastguard Worker         aacEncInit(hAacEncoder, hAacEncoder->InitFlags, &hAacEncoder->extParam);
1733*e5436536SAndroid Build Coastguard Worker 
1734*e5436536SAndroid Build Coastguard Worker     if (err != AACENC_OK) {
1735*e5436536SAndroid Build Coastguard Worker       /* keep init flags alive! */
1736*e5436536SAndroid Build Coastguard Worker       goto bail;
1737*e5436536SAndroid Build Coastguard Worker     }
1738*e5436536SAndroid Build Coastguard Worker     hAacEncoder->InitFlags = AACENC_INIT_NONE;
1739*e5436536SAndroid Build Coastguard Worker   }
1740*e5436536SAndroid Build Coastguard Worker 
1741*e5436536SAndroid Build Coastguard Worker   if (outargs != NULL) {
1742*e5436536SAndroid Build Coastguard Worker     FDKmemclear(outargs, sizeof(AACENC_OutArgs));
1743*e5436536SAndroid Build Coastguard Worker   }
1744*e5436536SAndroid Build Coastguard Worker 
1745*e5436536SAndroid Build Coastguard Worker   if (outBufDesc != NULL) {
1746*e5436536SAndroid Build Coastguard Worker     for (i = 0; i < outBufDesc->numBufs; i++) {
1747*e5436536SAndroid Build Coastguard Worker       if (outBufDesc->bufs[i] != NULL) {
1748*e5436536SAndroid Build Coastguard Worker         FDKmemclear(outBufDesc->bufs[i], outBufDesc->bufSizes[i]);
1749*e5436536SAndroid Build Coastguard Worker       }
1750*e5436536SAndroid Build Coastguard Worker     }
1751*e5436536SAndroid Build Coastguard Worker   }
1752*e5436536SAndroid Build Coastguard Worker 
1753*e5436536SAndroid Build Coastguard Worker   /*
1754*e5436536SAndroid Build Coastguard Worker    * If only encoder handle given, independent (re)initialization can be
1755*e5436536SAndroid Build Coastguard Worker    * triggered.
1756*e5436536SAndroid Build Coastguard Worker    */
1757*e5436536SAndroid Build Coastguard Worker   if ((inBufDesc == NULL) && (outBufDesc == NULL) && (inargs == NULL) &&
1758*e5436536SAndroid Build Coastguard Worker       (outargs == NULL)) {
1759*e5436536SAndroid Build Coastguard Worker     goto bail;
1760*e5436536SAndroid Build Coastguard Worker   }
1761*e5436536SAndroid Build Coastguard Worker 
1762*e5436536SAndroid Build Coastguard Worker   /* check if buffer descriptors are filled out properly. */
1763*e5436536SAndroid Build Coastguard Worker   if ((inargs == NULL) || (outargs == NULL) ||
1764*e5436536SAndroid Build Coastguard Worker       ((AACENC_OK != validateBufDesc(inBufDesc)) &&
1765*e5436536SAndroid Build Coastguard Worker        (inargs->numInSamples > 0)) ||
1766*e5436536SAndroid Build Coastguard Worker       (AACENC_OK != validateBufDesc(outBufDesc))) {
1767*e5436536SAndroid Build Coastguard Worker     err = AACENC_UNSUPPORTED_PARAMETER;
1768*e5436536SAndroid Build Coastguard Worker     goto bail;
1769*e5436536SAndroid Build Coastguard Worker   }
1770*e5436536SAndroid Build Coastguard Worker 
1771*e5436536SAndroid Build Coastguard Worker   /* reset buffer wich signals number of valid bytes in output bitstream buffer
1772*e5436536SAndroid Build Coastguard Worker    */
1773*e5436536SAndroid Build Coastguard Worker   FDKmemclear(outBytes, hAacEncoder->aacConfig.nSubFrames * sizeof(INT));
1774*e5436536SAndroid Build Coastguard Worker 
1775*e5436536SAndroid Build Coastguard Worker   /*
1776*e5436536SAndroid Build Coastguard Worker    * Manage incoming audio samples.
1777*e5436536SAndroid Build Coastguard Worker    */
1778*e5436536SAndroid Build Coastguard Worker   if ((inBufDesc != NULL) && (inargs->numInSamples > 0) &&
1779*e5436536SAndroid Build Coastguard Worker       (getBufDescIdx(inBufDesc, IN_AUDIO_DATA) != -1)) {
1780*e5436536SAndroid Build Coastguard Worker     /* Fetch data until nSamplesToRead reached */
1781*e5436536SAndroid Build Coastguard Worker     INT idx = getBufDescIdx(inBufDesc, IN_AUDIO_DATA);
1782*e5436536SAndroid Build Coastguard Worker     INT newSamples =
1783*e5436536SAndroid Build Coastguard Worker         fixMax(0, fixMin(inargs->numInSamples, hAacEncoder->nSamplesToRead -
1784*e5436536SAndroid Build Coastguard Worker                                                    hAacEncoder->nSamplesRead));
1785*e5436536SAndroid Build Coastguard Worker     INT_PCM *pIn =
1786*e5436536SAndroid Build Coastguard Worker         hAacEncoder->inputBuffer +
1787*e5436536SAndroid Build Coastguard Worker         hAacEncoder->inputBufferOffset / hAacEncoder->aacConfig.nChannels +
1788*e5436536SAndroid Build Coastguard Worker         hAacEncoder->nSamplesRead / hAacEncoder->extParam.nChannels;
1789*e5436536SAndroid Build Coastguard Worker     newSamples -=
1790*e5436536SAndroid Build Coastguard Worker         (newSamples %
1791*e5436536SAndroid Build Coastguard Worker          hAacEncoder->extParam
1792*e5436536SAndroid Build Coastguard Worker              .nChannels); /* process multiple samples of input channels */
1793*e5436536SAndroid Build Coastguard Worker 
1794*e5436536SAndroid Build Coastguard Worker     /* Copy new input samples to internal buffer */
1795*e5436536SAndroid Build Coastguard Worker     if (inBufDesc->bufElSizes[idx] == (INT)sizeof(INT_PCM)) {
1796*e5436536SAndroid Build Coastguard Worker       FDK_deinterleave((INT_PCM *)inBufDesc->bufs[idx], pIn,
1797*e5436536SAndroid Build Coastguard Worker                        hAacEncoder->extParam.nChannels,
1798*e5436536SAndroid Build Coastguard Worker                        newSamples / hAacEncoder->extParam.nChannels,
1799*e5436536SAndroid Build Coastguard Worker                        hAacEncoder->inputBufferSizePerChannel);
1800*e5436536SAndroid Build Coastguard Worker     } else if (inBufDesc->bufElSizes[idx] > (INT)sizeof(INT_PCM)) {
1801*e5436536SAndroid Build Coastguard Worker       FDK_deinterleave((LONG *)inBufDesc->bufs[idx], pIn,
1802*e5436536SAndroid Build Coastguard Worker                        hAacEncoder->extParam.nChannels,
1803*e5436536SAndroid Build Coastguard Worker                        newSamples / hAacEncoder->extParam.nChannels,
1804*e5436536SAndroid Build Coastguard Worker                        hAacEncoder->inputBufferSizePerChannel);
1805*e5436536SAndroid Build Coastguard Worker     } else {
1806*e5436536SAndroid Build Coastguard Worker       FDK_deinterleave((SHORT *)inBufDesc->bufs[idx], pIn,
1807*e5436536SAndroid Build Coastguard Worker                        hAacEncoder->extParam.nChannels,
1808*e5436536SAndroid Build Coastguard Worker                        newSamples / hAacEncoder->extParam.nChannels,
1809*e5436536SAndroid Build Coastguard Worker                        hAacEncoder->inputBufferSizePerChannel);
1810*e5436536SAndroid Build Coastguard Worker     }
1811*e5436536SAndroid Build Coastguard Worker     hAacEncoder->nSamplesRead += newSamples;
1812*e5436536SAndroid Build Coastguard Worker 
1813*e5436536SAndroid Build Coastguard Worker     /* Number of fetched input buffer samples. */
1814*e5436536SAndroid Build Coastguard Worker     outargs->numInSamples = newSamples;
1815*e5436536SAndroid Build Coastguard Worker   }
1816*e5436536SAndroid Build Coastguard Worker 
1817*e5436536SAndroid Build Coastguard Worker   /* input buffer completely filled ? */
1818*e5436536SAndroid Build Coastguard Worker   if (hAacEncoder->nSamplesRead < hAacEncoder->nSamplesToRead) {
1819*e5436536SAndroid Build Coastguard Worker     /* - eof reached and flushing enabled, or
1820*e5436536SAndroid Build Coastguard Worker        - return to main and wait for further incoming audio samples */
1821*e5436536SAndroid Build Coastguard Worker     if (inargs->numInSamples == -1) {
1822*e5436536SAndroid Build Coastguard Worker       if ((hAacEncoder->nZerosAppended < hAacEncoder->nDelay)) {
1823*e5436536SAndroid Build Coastguard Worker         int nZeros = (hAacEncoder->nSamplesToRead - hAacEncoder->nSamplesRead) /
1824*e5436536SAndroid Build Coastguard Worker                      hAacEncoder->extParam.nChannels;
1825*e5436536SAndroid Build Coastguard Worker 
1826*e5436536SAndroid Build Coastguard Worker         FDK_ASSERT(nZeros >= 0);
1827*e5436536SAndroid Build Coastguard Worker 
1828*e5436536SAndroid Build Coastguard Worker         /* clear out until end-of-buffer */
1829*e5436536SAndroid Build Coastguard Worker         if (nZeros) {
1830*e5436536SAndroid Build Coastguard Worker           INT_PCM *pIn =
1831*e5436536SAndroid Build Coastguard Worker               hAacEncoder->inputBuffer +
1832*e5436536SAndroid Build Coastguard Worker               hAacEncoder->inputBufferOffset /
1833*e5436536SAndroid Build Coastguard Worker                   hAacEncoder->aacConfig.nChannels +
1834*e5436536SAndroid Build Coastguard Worker               hAacEncoder->nSamplesRead / hAacEncoder->extParam.nChannels;
1835*e5436536SAndroid Build Coastguard Worker           for (i = 0; i < (int)hAacEncoder->extParam.nChannels; i++) {
1836*e5436536SAndroid Build Coastguard Worker             FDKmemclear(pIn + i * hAacEncoder->inputBufferSizePerChannel,
1837*e5436536SAndroid Build Coastguard Worker                         sizeof(INT_PCM) * nZeros);
1838*e5436536SAndroid Build Coastguard Worker           }
1839*e5436536SAndroid Build Coastguard Worker           hAacEncoder->nZerosAppended += nZeros;
1840*e5436536SAndroid Build Coastguard Worker           hAacEncoder->nSamplesRead = hAacEncoder->nSamplesToRead;
1841*e5436536SAndroid Build Coastguard Worker         }
1842*e5436536SAndroid Build Coastguard Worker       } else {                   /* flushing completed */
1843*e5436536SAndroid Build Coastguard Worker         err = AACENC_ENCODE_EOF; /* eof reached */
1844*e5436536SAndroid Build Coastguard Worker         goto bail;
1845*e5436536SAndroid Build Coastguard Worker       }
1846*e5436536SAndroid Build Coastguard Worker     } else {     /* inargs->numInSamples!= -1 */
1847*e5436536SAndroid Build Coastguard Worker       goto bail; /* not enough samples in input buffer and no flushing enabled
1848*e5436536SAndroid Build Coastguard Worker                   */
1849*e5436536SAndroid Build Coastguard Worker     }
1850*e5436536SAndroid Build Coastguard Worker   }
1851*e5436536SAndroid Build Coastguard Worker 
1852*e5436536SAndroid Build Coastguard Worker   /* init payload */
1853*e5436536SAndroid Build Coastguard Worker   FDKmemclear(hAacEncoder->extPayload,
1854*e5436536SAndroid Build Coastguard Worker               sizeof(AACENC_EXT_PAYLOAD) * MAX_TOTAL_EXT_PAYLOADS);
1855*e5436536SAndroid Build Coastguard Worker   for (i = 0; i < MAX_TOTAL_EXT_PAYLOADS; i++) {
1856*e5436536SAndroid Build Coastguard Worker     hAacEncoder->extPayload[i].associatedChElement = -1;
1857*e5436536SAndroid Build Coastguard Worker   }
1858*e5436536SAndroid Build Coastguard Worker   if (hAacEncoder->pSbrPayload != NULL) {
1859*e5436536SAndroid Build Coastguard Worker     FDKmemclear(hAacEncoder->pSbrPayload, sizeof(*hAacEncoder->pSbrPayload));
1860*e5436536SAndroid Build Coastguard Worker   }
1861*e5436536SAndroid Build Coastguard Worker 
1862*e5436536SAndroid Build Coastguard Worker   /*
1863*e5436536SAndroid Build Coastguard Worker    * Calculate Meta Data info.
1864*e5436536SAndroid Build Coastguard Worker    */
1865*e5436536SAndroid Build Coastguard Worker   if ((hAacEncoder->hMetadataEnc != NULL) &&
1866*e5436536SAndroid Build Coastguard Worker       (hAacEncoder->metaDataAllowed != 0)) {
1867*e5436536SAndroid Build Coastguard Worker     const AACENC_MetaData *pMetaData = NULL;
1868*e5436536SAndroid Build Coastguard Worker     AACENC_EXT_PAYLOAD *pMetaDataExtPayload = NULL;
1869*e5436536SAndroid Build Coastguard Worker     UINT nMetaDataExtensions = 0;
1870*e5436536SAndroid Build Coastguard Worker     INT matrix_mixdown_idx = 0;
1871*e5436536SAndroid Build Coastguard Worker 
1872*e5436536SAndroid Build Coastguard Worker     /* New meta data info available ? */
1873*e5436536SAndroid Build Coastguard Worker     if (getBufDescIdx(inBufDesc, IN_METADATA_SETUP) != -1) {
1874*e5436536SAndroid Build Coastguard Worker       pMetaData =
1875*e5436536SAndroid Build Coastguard Worker           (AACENC_MetaData *)
1876*e5436536SAndroid Build Coastguard Worker               inBufDesc->bufs[getBufDescIdx(inBufDesc, IN_METADATA_SETUP)];
1877*e5436536SAndroid Build Coastguard Worker     }
1878*e5436536SAndroid Build Coastguard Worker 
1879*e5436536SAndroid Build Coastguard Worker     FDK_MetadataEnc_Process(
1880*e5436536SAndroid Build Coastguard Worker         hAacEncoder->hMetadataEnc,
1881*e5436536SAndroid Build Coastguard Worker         hAacEncoder->inputBuffer + hAacEncoder->inputBufferOffset /
1882*e5436536SAndroid Build Coastguard Worker                                        hAacEncoder->coderConfig.noChannels,
1883*e5436536SAndroid Build Coastguard Worker         hAacEncoder->inputBufferSizePerChannel, hAacEncoder->nSamplesRead,
1884*e5436536SAndroid Build Coastguard Worker         pMetaData, &pMetaDataExtPayload, &nMetaDataExtensions,
1885*e5436536SAndroid Build Coastguard Worker         &matrix_mixdown_idx);
1886*e5436536SAndroid Build Coastguard Worker 
1887*e5436536SAndroid Build Coastguard Worker     for (i = 0; i < (INT)nMetaDataExtensions;
1888*e5436536SAndroid Build Coastguard Worker          i++) { /* Get meta data extension payload. */
1889*e5436536SAndroid Build Coastguard Worker       hAacEncoder->extPayload[nExtensions++] = pMetaDataExtPayload[i];
1890*e5436536SAndroid Build Coastguard Worker     }
1891*e5436536SAndroid Build Coastguard Worker 
1892*e5436536SAndroid Build Coastguard Worker     if ((matrix_mixdown_idx != -1) &&
1893*e5436536SAndroid Build Coastguard Worker         ((hAacEncoder->extParam.userChannelMode == MODE_1_2_2) ||
1894*e5436536SAndroid Build Coastguard Worker          (hAacEncoder->extParam.userChannelMode == MODE_1_2_2_1))) {
1895*e5436536SAndroid Build Coastguard Worker       /* Set matrix mixdown coefficient. */
1896*e5436536SAndroid Build Coastguard Worker       UINT pceValue = (UINT)((0 << 3) | ((matrix_mixdown_idx & 0x3) << 1) | 1);
1897*e5436536SAndroid Build Coastguard Worker       if (hAacEncoder->extParam.userPceAdditions != pceValue) {
1898*e5436536SAndroid Build Coastguard Worker         hAacEncoder->extParam.userPceAdditions = pceValue;
1899*e5436536SAndroid Build Coastguard Worker         hAacEncoder->InitFlags |= AACENC_INIT_TRANSPORT;
1900*e5436536SAndroid Build Coastguard Worker       }
1901*e5436536SAndroid Build Coastguard Worker     }
1902*e5436536SAndroid Build Coastguard Worker   }
1903*e5436536SAndroid Build Coastguard Worker 
1904*e5436536SAndroid Build Coastguard Worker   /*
1905*e5436536SAndroid Build Coastguard Worker    * Encode MPS data.
1906*e5436536SAndroid Build Coastguard Worker    */
1907*e5436536SAndroid Build Coastguard Worker   if ((hAacEncoder->hMpsEnc != NULL) &&
1908*e5436536SAndroid Build Coastguard Worker       (hAacEncoder->aacConfig.syntaxFlags & AC_LD_MPS)) {
1909*e5436536SAndroid Build Coastguard Worker     AACENC_EXT_PAYLOAD mpsExtensionPayload;
1910*e5436536SAndroid Build Coastguard Worker     FDKmemclear(&mpsExtensionPayload, sizeof(AACENC_EXT_PAYLOAD));
1911*e5436536SAndroid Build Coastguard Worker 
1912*e5436536SAndroid Build Coastguard Worker     if (MPS_ENCODER_OK !=
1913*e5436536SAndroid Build Coastguard Worker         FDK_MpegsEnc_Process(
1914*e5436536SAndroid Build Coastguard Worker             hAacEncoder->hMpsEnc,
1915*e5436536SAndroid Build Coastguard Worker             hAacEncoder->inputBuffer + hAacEncoder->inputBufferOffset /
1916*e5436536SAndroid Build Coastguard Worker                                            hAacEncoder->coderConfig.noChannels,
1917*e5436536SAndroid Build Coastguard Worker             hAacEncoder->nSamplesRead, &mpsExtensionPayload)) {
1918*e5436536SAndroid Build Coastguard Worker       err = AACENC_ENCODE_ERROR;
1919*e5436536SAndroid Build Coastguard Worker       goto bail;
1920*e5436536SAndroid Build Coastguard Worker     }
1921*e5436536SAndroid Build Coastguard Worker 
1922*e5436536SAndroid Build Coastguard Worker     if ((mpsExtensionPayload.pData != NULL) &&
1923*e5436536SAndroid Build Coastguard Worker         ((mpsExtensionPayload.dataSize != 0))) {
1924*e5436536SAndroid Build Coastguard Worker       hAacEncoder->extPayload[nExtensions++] = mpsExtensionPayload;
1925*e5436536SAndroid Build Coastguard Worker     }
1926*e5436536SAndroid Build Coastguard Worker   }
1927*e5436536SAndroid Build Coastguard Worker 
1928*e5436536SAndroid Build Coastguard Worker   if ((NULL != hAacEncoder->hEnvEnc) && (NULL != hAacEncoder->pSbrPayload) &&
1929*e5436536SAndroid Build Coastguard Worker       isSbrActive(&hAacEncoder->aacConfig)) {
1930*e5436536SAndroid Build Coastguard Worker     INT nPayload = 0;
1931*e5436536SAndroid Build Coastguard Worker 
1932*e5436536SAndroid Build Coastguard Worker     /*
1933*e5436536SAndroid Build Coastguard Worker      * Encode SBR data.
1934*e5436536SAndroid Build Coastguard Worker      */
1935*e5436536SAndroid Build Coastguard Worker     if (sbrEncoder_EncodeFrame(hAacEncoder->hEnvEnc, hAacEncoder->inputBuffer,
1936*e5436536SAndroid Build Coastguard Worker                                hAacEncoder->inputBufferSizePerChannel,
1937*e5436536SAndroid Build Coastguard Worker                                hAacEncoder->pSbrPayload->dataSize[nPayload],
1938*e5436536SAndroid Build Coastguard Worker                                hAacEncoder->pSbrPayload->data[nPayload])) {
1939*e5436536SAndroid Build Coastguard Worker       err = AACENC_ENCODE_ERROR;
1940*e5436536SAndroid Build Coastguard Worker       goto bail;
1941*e5436536SAndroid Build Coastguard Worker     } else {
1942*e5436536SAndroid Build Coastguard Worker       /* Add SBR extension payload */
1943*e5436536SAndroid Build Coastguard Worker       for (i = 0; i < (8); i++) {
1944*e5436536SAndroid Build Coastguard Worker         if (hAacEncoder->pSbrPayload->dataSize[nPayload][i] > 0) {
1945*e5436536SAndroid Build Coastguard Worker           hAacEncoder->extPayload[nExtensions].pData =
1946*e5436536SAndroid Build Coastguard Worker               hAacEncoder->pSbrPayload->data[nPayload][i];
1947*e5436536SAndroid Build Coastguard Worker           {
1948*e5436536SAndroid Build Coastguard Worker             hAacEncoder->extPayload[nExtensions].dataSize =
1949*e5436536SAndroid Build Coastguard Worker                 hAacEncoder->pSbrPayload->dataSize[nPayload][i];
1950*e5436536SAndroid Build Coastguard Worker             hAacEncoder->extPayload[nExtensions].associatedChElement =
1951*e5436536SAndroid Build Coastguard Worker                 getAssociatedChElement(
1952*e5436536SAndroid Build Coastguard Worker                     &hAacEncoder->hEnvEnc->sbrElement[i]->elInfo,
1953*e5436536SAndroid Build Coastguard Worker                     &hAacEncoder->hAacEnc->channelMapping);
1954*e5436536SAndroid Build Coastguard Worker             if (hAacEncoder->extPayload[nExtensions].associatedChElement ==
1955*e5436536SAndroid Build Coastguard Worker                 -1) {
1956*e5436536SAndroid Build Coastguard Worker               err = AACENC_ENCODE_ERROR;
1957*e5436536SAndroid Build Coastguard Worker               goto bail;
1958*e5436536SAndroid Build Coastguard Worker             }
1959*e5436536SAndroid Build Coastguard Worker           }
1960*e5436536SAndroid Build Coastguard Worker           hAacEncoder->extPayload[nExtensions].dataType =
1961*e5436536SAndroid Build Coastguard Worker               EXT_SBR_DATA; /* Once SBR Encoder supports SBR CRC set
1962*e5436536SAndroid Build Coastguard Worker                                EXT_SBR_DATA_CRC */
1963*e5436536SAndroid Build Coastguard Worker           nExtensions++;    /* or EXT_SBR_DATA according to configuration. */
1964*e5436536SAndroid Build Coastguard Worker           FDK_ASSERT(nExtensions <= MAX_TOTAL_EXT_PAYLOADS);
1965*e5436536SAndroid Build Coastguard Worker         }
1966*e5436536SAndroid Build Coastguard Worker       }
1967*e5436536SAndroid Build Coastguard Worker       nPayload++;
1968*e5436536SAndroid Build Coastguard Worker     }
1969*e5436536SAndroid Build Coastguard Worker   } /* sbrEnabled */
1970*e5436536SAndroid Build Coastguard Worker 
1971*e5436536SAndroid Build Coastguard Worker   if ((inargs->numAncBytes > 0) &&
1972*e5436536SAndroid Build Coastguard Worker       (getBufDescIdx(inBufDesc, IN_ANCILLRY_DATA) != -1)) {
1973*e5436536SAndroid Build Coastguard Worker     INT idx = getBufDescIdx(inBufDesc, IN_ANCILLRY_DATA);
1974*e5436536SAndroid Build Coastguard Worker     hAacEncoder->extPayload[nExtensions].dataSize = inargs->numAncBytes * 8;
1975*e5436536SAndroid Build Coastguard Worker     hAacEncoder->extPayload[nExtensions].pData = (UCHAR *)inBufDesc->bufs[idx];
1976*e5436536SAndroid Build Coastguard Worker     hAacEncoder->extPayload[nExtensions].dataType = EXT_DATA_ELEMENT;
1977*e5436536SAndroid Build Coastguard Worker     hAacEncoder->extPayload[nExtensions].associatedChElement = -1;
1978*e5436536SAndroid Build Coastguard Worker     ancDataExtIdx = nExtensions; /* store index */
1979*e5436536SAndroid Build Coastguard Worker     nExtensions++;
1980*e5436536SAndroid Build Coastguard Worker   }
1981*e5436536SAndroid Build Coastguard Worker 
1982*e5436536SAndroid Build Coastguard Worker   /*
1983*e5436536SAndroid Build Coastguard Worker    * Encode AAC - Core.
1984*e5436536SAndroid Build Coastguard Worker    */
1985*e5436536SAndroid Build Coastguard Worker   if (FDKaacEnc_EncodeFrame(hAacEncoder->hAacEnc, hAacEncoder->hTpEnc,
1986*e5436536SAndroid Build Coastguard Worker                             hAacEncoder->inputBuffer,
1987*e5436536SAndroid Build Coastguard Worker                             hAacEncoder->inputBufferSizePerChannel, outBytes,
1988*e5436536SAndroid Build Coastguard Worker                             hAacEncoder->extPayload) != AAC_ENC_OK) {
1989*e5436536SAndroid Build Coastguard Worker     err = AACENC_ENCODE_ERROR;
1990*e5436536SAndroid Build Coastguard Worker     goto bail;
1991*e5436536SAndroid Build Coastguard Worker   }
1992*e5436536SAndroid Build Coastguard Worker 
1993*e5436536SAndroid Build Coastguard Worker   if (ancDataExtIdx >= 0) {
1994*e5436536SAndroid Build Coastguard Worker     outargs->numAncBytes =
1995*e5436536SAndroid Build Coastguard Worker         inargs->numAncBytes -
1996*e5436536SAndroid Build Coastguard Worker         (hAacEncoder->extPayload[ancDataExtIdx].dataSize >> 3);
1997*e5436536SAndroid Build Coastguard Worker   }
1998*e5436536SAndroid Build Coastguard Worker 
1999*e5436536SAndroid Build Coastguard Worker   /* samples exhausted */
2000*e5436536SAndroid Build Coastguard Worker   hAacEncoder->nSamplesRead -= hAacEncoder->nSamplesToRead;
2001*e5436536SAndroid Build Coastguard Worker 
2002*e5436536SAndroid Build Coastguard Worker   /*
2003*e5436536SAndroid Build Coastguard Worker    * Delay balancing buffer handling
2004*e5436536SAndroid Build Coastguard Worker    */
2005*e5436536SAndroid Build Coastguard Worker   if (isSbrActive(&hAacEncoder->aacConfig)) {
2006*e5436536SAndroid Build Coastguard Worker     sbrEncoder_UpdateBuffers(hAacEncoder->hEnvEnc, hAacEncoder->inputBuffer,
2007*e5436536SAndroid Build Coastguard Worker                              hAacEncoder->inputBufferSizePerChannel);
2008*e5436536SAndroid Build Coastguard Worker   }
2009*e5436536SAndroid Build Coastguard Worker 
2010*e5436536SAndroid Build Coastguard Worker   /*
2011*e5436536SAndroid Build Coastguard Worker    * Make bitstream public
2012*e5436536SAndroid Build Coastguard Worker    */
2013*e5436536SAndroid Build Coastguard Worker   if ((outBufDesc != NULL) && (outBufDesc->numBufs >= 1)) {
2014*e5436536SAndroid Build Coastguard Worker     INT bsIdx = getBufDescIdx(outBufDesc, OUT_BITSTREAM_DATA);
2015*e5436536SAndroid Build Coastguard Worker     INT auIdx = getBufDescIdx(outBufDesc, OUT_AU_SIZES);
2016*e5436536SAndroid Build Coastguard Worker 
2017*e5436536SAndroid Build Coastguard Worker     for (i = 0, nBsBytes = 0; i < hAacEncoder->aacConfig.nSubFrames; i++) {
2018*e5436536SAndroid Build Coastguard Worker       nBsBytes += outBytes[i];
2019*e5436536SAndroid Build Coastguard Worker 
2020*e5436536SAndroid Build Coastguard Worker       if (auIdx != -1) {
2021*e5436536SAndroid Build Coastguard Worker         ((INT *)outBufDesc->bufs[auIdx])[i] = outBytes[i];
2022*e5436536SAndroid Build Coastguard Worker       }
2023*e5436536SAndroid Build Coastguard Worker     }
2024*e5436536SAndroid Build Coastguard Worker 
2025*e5436536SAndroid Build Coastguard Worker     if ((bsIdx != -1) && (outBufDesc->bufSizes[bsIdx] >= nBsBytes)) {
2026*e5436536SAndroid Build Coastguard Worker       FDKmemcpy(outBufDesc->bufs[bsIdx], hAacEncoder->outBuffer,
2027*e5436536SAndroid Build Coastguard Worker                 sizeof(UCHAR) * nBsBytes);
2028*e5436536SAndroid Build Coastguard Worker       outargs->numOutBytes = nBsBytes;
2029*e5436536SAndroid Build Coastguard Worker       outargs->bitResState =
2030*e5436536SAndroid Build Coastguard Worker           FDKaacEnc_GetBitReservoirState(hAacEncoder->hAacEnc);
2031*e5436536SAndroid Build Coastguard Worker     } else {
2032*e5436536SAndroid Build Coastguard Worker       /* output buffer too small, can't write valid bitstream */
2033*e5436536SAndroid Build Coastguard Worker       err = AACENC_ENCODE_ERROR;
2034*e5436536SAndroid Build Coastguard Worker       goto bail;
2035*e5436536SAndroid Build Coastguard Worker     }
2036*e5436536SAndroid Build Coastguard Worker   }
2037*e5436536SAndroid Build Coastguard Worker 
2038*e5436536SAndroid Build Coastguard Worker bail:
2039*e5436536SAndroid Build Coastguard Worker   if (err == AACENC_ENCODE_ERROR) {
2040*e5436536SAndroid Build Coastguard Worker     /* All encoder modules have to be initialized */
2041*e5436536SAndroid Build Coastguard Worker     hAacEncoder->InitFlags = AACENC_INIT_ALL;
2042*e5436536SAndroid Build Coastguard Worker   }
2043*e5436536SAndroid Build Coastguard Worker 
2044*e5436536SAndroid Build Coastguard Worker   return err;
2045*e5436536SAndroid Build Coastguard Worker }
2046*e5436536SAndroid Build Coastguard Worker 
aacEncGetConf(HANDLE_AACENCODER hAacEncoder,UINT * size,UCHAR * confBuffer)2047*e5436536SAndroid Build Coastguard Worker static AAC_ENCODER_ERROR aacEncGetConf(HANDLE_AACENCODER hAacEncoder,
2048*e5436536SAndroid Build Coastguard Worker                                        UINT *size, UCHAR *confBuffer) {
2049*e5436536SAndroid Build Coastguard Worker   FDK_BITSTREAM tmpConf;
2050*e5436536SAndroid Build Coastguard Worker   UINT confType;
2051*e5436536SAndroid Build Coastguard Worker   UCHAR buf[64];
2052*e5436536SAndroid Build Coastguard Worker   int err;
2053*e5436536SAndroid Build Coastguard Worker 
2054*e5436536SAndroid Build Coastguard Worker   /* Init bit buffer */
2055*e5436536SAndroid Build Coastguard Worker   FDKinitBitStream(&tmpConf, buf, 64, 0, BS_WRITER);
2056*e5436536SAndroid Build Coastguard Worker 
2057*e5436536SAndroid Build Coastguard Worker   /* write conf in tmp buffer */
2058*e5436536SAndroid Build Coastguard Worker   err = transportEnc_GetConf(hAacEncoder->hTpEnc, &hAacEncoder->coderConfig,
2059*e5436536SAndroid Build Coastguard Worker                              &tmpConf, &confType);
2060*e5436536SAndroid Build Coastguard Worker 
2061*e5436536SAndroid Build Coastguard Worker   /* copy data to outbuffer: length in bytes */
2062*e5436536SAndroid Build Coastguard Worker   FDKbyteAlign(&tmpConf, 0);
2063*e5436536SAndroid Build Coastguard Worker 
2064*e5436536SAndroid Build Coastguard Worker   /* Check buffer size */
2065*e5436536SAndroid Build Coastguard Worker   if (FDKgetValidBits(&tmpConf) > ((*size) << 3)) return AAC_ENC_UNKNOWN;
2066*e5436536SAndroid Build Coastguard Worker 
2067*e5436536SAndroid Build Coastguard Worker   FDKfetchBuffer(&tmpConf, confBuffer, size);
2068*e5436536SAndroid Build Coastguard Worker 
2069*e5436536SAndroid Build Coastguard Worker   if (err != 0)
2070*e5436536SAndroid Build Coastguard Worker     return AAC_ENC_UNKNOWN;
2071*e5436536SAndroid Build Coastguard Worker   else
2072*e5436536SAndroid Build Coastguard Worker     return AAC_ENC_OK;
2073*e5436536SAndroid Build Coastguard Worker }
2074*e5436536SAndroid Build Coastguard Worker 
aacEncGetLibInfo(LIB_INFO * info)2075*e5436536SAndroid Build Coastguard Worker AACENC_ERROR aacEncGetLibInfo(LIB_INFO *info) {
2076*e5436536SAndroid Build Coastguard Worker   int i = 0;
2077*e5436536SAndroid Build Coastguard Worker 
2078*e5436536SAndroid Build Coastguard Worker   if (info == NULL) {
2079*e5436536SAndroid Build Coastguard Worker     return AACENC_INVALID_HANDLE;
2080*e5436536SAndroid Build Coastguard Worker   }
2081*e5436536SAndroid Build Coastguard Worker 
2082*e5436536SAndroid Build Coastguard Worker   FDK_toolsGetLibInfo(info);
2083*e5436536SAndroid Build Coastguard Worker   transportEnc_GetLibInfo(info);
2084*e5436536SAndroid Build Coastguard Worker   sbrEncoder_GetLibInfo(info);
2085*e5436536SAndroid Build Coastguard Worker   FDK_MpegsEnc_GetLibInfo(info);
2086*e5436536SAndroid Build Coastguard Worker 
2087*e5436536SAndroid Build Coastguard Worker   /* search for next free tab */
2088*e5436536SAndroid Build Coastguard Worker   for (i = 0; i < FDK_MODULE_LAST; i++) {
2089*e5436536SAndroid Build Coastguard Worker     if (info[i].module_id == FDK_NONE) break;
2090*e5436536SAndroid Build Coastguard Worker   }
2091*e5436536SAndroid Build Coastguard Worker   if (i == FDK_MODULE_LAST) {
2092*e5436536SAndroid Build Coastguard Worker     return AACENC_INIT_ERROR;
2093*e5436536SAndroid Build Coastguard Worker   }
2094*e5436536SAndroid Build Coastguard Worker 
2095*e5436536SAndroid Build Coastguard Worker   info[i].module_id = FDK_AACENC;
2096*e5436536SAndroid Build Coastguard Worker   info[i].build_date = AACENCODER_LIB_BUILD_DATE;
2097*e5436536SAndroid Build Coastguard Worker   info[i].build_time = AACENCODER_LIB_BUILD_TIME;
2098*e5436536SAndroid Build Coastguard Worker   info[i].title = AACENCODER_LIB_TITLE;
2099*e5436536SAndroid Build Coastguard Worker   info[i].version =
2100*e5436536SAndroid Build Coastguard Worker       LIB_VERSION(AACENCODER_LIB_VL0, AACENCODER_LIB_VL1, AACENCODER_LIB_VL2);
2101*e5436536SAndroid Build Coastguard Worker   ;
2102*e5436536SAndroid Build Coastguard Worker   LIB_VERSION_STRING(&info[i]);
2103*e5436536SAndroid Build Coastguard Worker 
2104*e5436536SAndroid Build Coastguard Worker   /* Capability flags */
2105*e5436536SAndroid Build Coastguard Worker   info[i].flags = 0 | CAPF_AAC_1024 | CAPF_AAC_LC | CAPF_AAC_512 |
2106*e5436536SAndroid Build Coastguard Worker                   CAPF_AAC_480 | CAPF_AAC_DRC | CAPF_AAC_ELD_DOWNSCALE;
2107*e5436536SAndroid Build Coastguard Worker   /* End of flags */
2108*e5436536SAndroid Build Coastguard Worker 
2109*e5436536SAndroid Build Coastguard Worker   return AACENC_OK;
2110*e5436536SAndroid Build Coastguard Worker }
2111*e5436536SAndroid Build Coastguard Worker 
aacEncoder_SetParam(const HANDLE_AACENCODER hAacEncoder,const AACENC_PARAM param,const UINT value)2112*e5436536SAndroid Build Coastguard Worker AACENC_ERROR aacEncoder_SetParam(const HANDLE_AACENCODER hAacEncoder,
2113*e5436536SAndroid Build Coastguard Worker                                  const AACENC_PARAM param, const UINT value) {
2114*e5436536SAndroid Build Coastguard Worker   AACENC_ERROR err = AACENC_OK;
2115*e5436536SAndroid Build Coastguard Worker   USER_PARAM *settings = &hAacEncoder->extParam;
2116*e5436536SAndroid Build Coastguard Worker 
2117*e5436536SAndroid Build Coastguard Worker   /* check encoder handle */
2118*e5436536SAndroid Build Coastguard Worker   if (hAacEncoder == NULL) {
2119*e5436536SAndroid Build Coastguard Worker     err = AACENC_INVALID_HANDLE;
2120*e5436536SAndroid Build Coastguard Worker     goto bail;
2121*e5436536SAndroid Build Coastguard Worker   }
2122*e5436536SAndroid Build Coastguard Worker 
2123*e5436536SAndroid Build Coastguard Worker   /* apply param value */
2124*e5436536SAndroid Build Coastguard Worker   switch (param) {
2125*e5436536SAndroid Build Coastguard Worker     case AACENC_AOT:
2126*e5436536SAndroid Build Coastguard Worker       if (settings->userAOT != (AUDIO_OBJECT_TYPE)value) {
2127*e5436536SAndroid Build Coastguard Worker         /* check if AOT matches the allocated modules */
2128*e5436536SAndroid Build Coastguard Worker         switch (value) {
2129*e5436536SAndroid Build Coastguard Worker           case AOT_PS:
2130*e5436536SAndroid Build Coastguard Worker             if (!(hAacEncoder->encoder_modis & (ENC_MODE_FLAG_PS))) {
2131*e5436536SAndroid Build Coastguard Worker               err = AACENC_INVALID_CONFIG;
2132*e5436536SAndroid Build Coastguard Worker               goto bail;
2133*e5436536SAndroid Build Coastguard Worker             }
2134*e5436536SAndroid Build Coastguard Worker             FDK_FALLTHROUGH;
2135*e5436536SAndroid Build Coastguard Worker           case AOT_SBR:
2136*e5436536SAndroid Build Coastguard Worker           case AOT_MP2_SBR:
2137*e5436536SAndroid Build Coastguard Worker             if (!(hAacEncoder->encoder_modis & (ENC_MODE_FLAG_SBR))) {
2138*e5436536SAndroid Build Coastguard Worker               err = AACENC_INVALID_CONFIG;
2139*e5436536SAndroid Build Coastguard Worker               goto bail;
2140*e5436536SAndroid Build Coastguard Worker             }
2141*e5436536SAndroid Build Coastguard Worker             FDK_FALLTHROUGH;
2142*e5436536SAndroid Build Coastguard Worker           case AOT_AAC_LC:
2143*e5436536SAndroid Build Coastguard Worker           case AOT_MP2_AAC_LC:
2144*e5436536SAndroid Build Coastguard Worker           case AOT_ER_AAC_LD:
2145*e5436536SAndroid Build Coastguard Worker           case AOT_ER_AAC_ELD:
2146*e5436536SAndroid Build Coastguard Worker             if (!(hAacEncoder->encoder_modis & (ENC_MODE_FLAG_AAC))) {
2147*e5436536SAndroid Build Coastguard Worker               err = AACENC_INVALID_CONFIG;
2148*e5436536SAndroid Build Coastguard Worker               goto bail;
2149*e5436536SAndroid Build Coastguard Worker             }
2150*e5436536SAndroid Build Coastguard Worker             break;
2151*e5436536SAndroid Build Coastguard Worker           default:
2152*e5436536SAndroid Build Coastguard Worker             err = AACENC_INVALID_CONFIG;
2153*e5436536SAndroid Build Coastguard Worker             goto bail;
2154*e5436536SAndroid Build Coastguard Worker         } /* switch value */
2155*e5436536SAndroid Build Coastguard Worker         settings->userAOT = (AUDIO_OBJECT_TYPE)value;
2156*e5436536SAndroid Build Coastguard Worker         hAacEncoder->InitFlags |=
2157*e5436536SAndroid Build Coastguard Worker             AACENC_INIT_CONFIG | AACENC_INIT_STATES | AACENC_INIT_TRANSPORT;
2158*e5436536SAndroid Build Coastguard Worker       }
2159*e5436536SAndroid Build Coastguard Worker       break;
2160*e5436536SAndroid Build Coastguard Worker     case AACENC_BITRATE:
2161*e5436536SAndroid Build Coastguard Worker       if (settings->userBitrate != value) {
2162*e5436536SAndroid Build Coastguard Worker         settings->userBitrate = value;
2163*e5436536SAndroid Build Coastguard Worker         hAacEncoder->InitFlags |= AACENC_INIT_CONFIG | AACENC_INIT_TRANSPORT;
2164*e5436536SAndroid Build Coastguard Worker       }
2165*e5436536SAndroid Build Coastguard Worker       break;
2166*e5436536SAndroid Build Coastguard Worker     case AACENC_BITRATEMODE:
2167*e5436536SAndroid Build Coastguard Worker       if (settings->userBitrateMode != value) {
2168*e5436536SAndroid Build Coastguard Worker         switch (value) {
2169*e5436536SAndroid Build Coastguard Worker           case 0:
2170*e5436536SAndroid Build Coastguard Worker           case 1:
2171*e5436536SAndroid Build Coastguard Worker           case 2:
2172*e5436536SAndroid Build Coastguard Worker           case 3:
2173*e5436536SAndroid Build Coastguard Worker           case 4:
2174*e5436536SAndroid Build Coastguard Worker           case 5:
2175*e5436536SAndroid Build Coastguard Worker             settings->userBitrateMode = value;
2176*e5436536SAndroid Build Coastguard Worker             hAacEncoder->InitFlags |=
2177*e5436536SAndroid Build Coastguard Worker                 AACENC_INIT_CONFIG | AACENC_INIT_TRANSPORT;
2178*e5436536SAndroid Build Coastguard Worker             break;
2179*e5436536SAndroid Build Coastguard Worker           default:
2180*e5436536SAndroid Build Coastguard Worker             err = AACENC_INVALID_CONFIG;
2181*e5436536SAndroid Build Coastguard Worker             break;
2182*e5436536SAndroid Build Coastguard Worker         } /* switch value */
2183*e5436536SAndroid Build Coastguard Worker       }
2184*e5436536SAndroid Build Coastguard Worker       break;
2185*e5436536SAndroid Build Coastguard Worker     case AACENC_SAMPLERATE:
2186*e5436536SAndroid Build Coastguard Worker       if (settings->userSamplerate != value) {
2187*e5436536SAndroid Build Coastguard Worker         if (!((value == 8000) || (value == 11025) || (value == 12000) ||
2188*e5436536SAndroid Build Coastguard Worker               (value == 16000) || (value == 22050) || (value == 24000) ||
2189*e5436536SAndroid Build Coastguard Worker               (value == 32000) || (value == 44100) || (value == 48000) ||
2190*e5436536SAndroid Build Coastguard Worker               (value == 64000) || (value == 88200) || (value == 96000))) {
2191*e5436536SAndroid Build Coastguard Worker           err = AACENC_INVALID_CONFIG;
2192*e5436536SAndroid Build Coastguard Worker           break;
2193*e5436536SAndroid Build Coastguard Worker         }
2194*e5436536SAndroid Build Coastguard Worker         settings->userSamplerate = value;
2195*e5436536SAndroid Build Coastguard Worker         hAacEncoder->nSamplesRead = 0; /* reset internal inputbuffer */
2196*e5436536SAndroid Build Coastguard Worker         hAacEncoder->InitFlags |=
2197*e5436536SAndroid Build Coastguard Worker             AACENC_INIT_CONFIG | AACENC_INIT_STATES | AACENC_INIT_TRANSPORT;
2198*e5436536SAndroid Build Coastguard Worker       }
2199*e5436536SAndroid Build Coastguard Worker       break;
2200*e5436536SAndroid Build Coastguard Worker     case AACENC_CHANNELMODE:
2201*e5436536SAndroid Build Coastguard Worker       if (settings->userChannelMode != (CHANNEL_MODE)value) {
2202*e5436536SAndroid Build Coastguard Worker         if (((CHANNEL_MODE)value == MODE_212) &&
2203*e5436536SAndroid Build Coastguard Worker             (NULL != hAacEncoder->hMpsEnc)) {
2204*e5436536SAndroid Build Coastguard Worker           settings->userChannelMode = (CHANNEL_MODE)value;
2205*e5436536SAndroid Build Coastguard Worker           settings->nChannels = 2;
2206*e5436536SAndroid Build Coastguard Worker         } else {
2207*e5436536SAndroid Build Coastguard Worker           const CHANNEL_MODE_CONFIG_TAB *pConfig =
2208*e5436536SAndroid Build Coastguard Worker               FDKaacEnc_GetChannelModeConfiguration((CHANNEL_MODE)value);
2209*e5436536SAndroid Build Coastguard Worker           if (pConfig == NULL) {
2210*e5436536SAndroid Build Coastguard Worker             err = AACENC_INVALID_CONFIG;
2211*e5436536SAndroid Build Coastguard Worker             break;
2212*e5436536SAndroid Build Coastguard Worker           }
2213*e5436536SAndroid Build Coastguard Worker           if ((pConfig->nElements > hAacEncoder->nMaxAacElements) ||
2214*e5436536SAndroid Build Coastguard Worker               (pConfig->nChannelsEff > hAacEncoder->nMaxAacChannels)) {
2215*e5436536SAndroid Build Coastguard Worker             err = AACENC_INVALID_CONFIG;
2216*e5436536SAndroid Build Coastguard Worker             break;
2217*e5436536SAndroid Build Coastguard Worker           }
2218*e5436536SAndroid Build Coastguard Worker 
2219*e5436536SAndroid Build Coastguard Worker           settings->userChannelMode = (CHANNEL_MODE)value;
2220*e5436536SAndroid Build Coastguard Worker           settings->nChannels = pConfig->nChannels;
2221*e5436536SAndroid Build Coastguard Worker         }
2222*e5436536SAndroid Build Coastguard Worker         hAacEncoder->nSamplesRead = 0; /* reset internal inputbuffer */
2223*e5436536SAndroid Build Coastguard Worker         hAacEncoder->InitFlags |= AACENC_INIT_CONFIG | AACENC_INIT_TRANSPORT;
2224*e5436536SAndroid Build Coastguard Worker         if (!((value >= 1) && (value <= 6))) {
2225*e5436536SAndroid Build Coastguard Worker           hAacEncoder->InitFlags |= AACENC_INIT_STATES;
2226*e5436536SAndroid Build Coastguard Worker         }
2227*e5436536SAndroid Build Coastguard Worker       }
2228*e5436536SAndroid Build Coastguard Worker       break;
2229*e5436536SAndroid Build Coastguard Worker     case AACENC_BANDWIDTH:
2230*e5436536SAndroid Build Coastguard Worker       if (settings->userBandwidth != value) {
2231*e5436536SAndroid Build Coastguard Worker         settings->userBandwidth = value;
2232*e5436536SAndroid Build Coastguard Worker         hAacEncoder->InitFlags |= AACENC_INIT_CONFIG;
2233*e5436536SAndroid Build Coastguard Worker       }
2234*e5436536SAndroid Build Coastguard Worker       break;
2235*e5436536SAndroid Build Coastguard Worker     case AACENC_CHANNELORDER:
2236*e5436536SAndroid Build Coastguard Worker       if (hAacEncoder->aacConfig.channelOrder != (CHANNEL_ORDER)value) {
2237*e5436536SAndroid Build Coastguard Worker         if (!((value == 0) || (value == 1))) {
2238*e5436536SAndroid Build Coastguard Worker           err = AACENC_INVALID_CONFIG;
2239*e5436536SAndroid Build Coastguard Worker           break;
2240*e5436536SAndroid Build Coastguard Worker         }
2241*e5436536SAndroid Build Coastguard Worker         hAacEncoder->aacConfig.channelOrder = (CHANNEL_ORDER)value;
2242*e5436536SAndroid Build Coastguard Worker         hAacEncoder->nSamplesRead = 0; /* reset internal inputbuffer */
2243*e5436536SAndroid Build Coastguard Worker         hAacEncoder->InitFlags |=
2244*e5436536SAndroid Build Coastguard Worker             AACENC_INIT_CONFIG | AACENC_INIT_STATES | AACENC_INIT_TRANSPORT;
2245*e5436536SAndroid Build Coastguard Worker       }
2246*e5436536SAndroid Build Coastguard Worker       break;
2247*e5436536SAndroid Build Coastguard Worker     case AACENC_AFTERBURNER:
2248*e5436536SAndroid Build Coastguard Worker       if (settings->userAfterburner != value) {
2249*e5436536SAndroid Build Coastguard Worker         if (!((value == 0) || (value == 1))) {
2250*e5436536SAndroid Build Coastguard Worker           err = AACENC_INVALID_CONFIG;
2251*e5436536SAndroid Build Coastguard Worker           break;
2252*e5436536SAndroid Build Coastguard Worker         }
2253*e5436536SAndroid Build Coastguard Worker         settings->userAfterburner = value;
2254*e5436536SAndroid Build Coastguard Worker         hAacEncoder->InitFlags |= AACENC_INIT_CONFIG;
2255*e5436536SAndroid Build Coastguard Worker       }
2256*e5436536SAndroid Build Coastguard Worker       break;
2257*e5436536SAndroid Build Coastguard Worker     case AACENC_GRANULE_LENGTH:
2258*e5436536SAndroid Build Coastguard Worker       if (settings->userFramelength != value) {
2259*e5436536SAndroid Build Coastguard Worker         switch (value) {
2260*e5436536SAndroid Build Coastguard Worker           case 1024:
2261*e5436536SAndroid Build Coastguard Worker           case 512:
2262*e5436536SAndroid Build Coastguard Worker           case 480:
2263*e5436536SAndroid Build Coastguard Worker           case 256:
2264*e5436536SAndroid Build Coastguard Worker           case 240:
2265*e5436536SAndroid Build Coastguard Worker           case 128:
2266*e5436536SAndroid Build Coastguard Worker           case 120:
2267*e5436536SAndroid Build Coastguard Worker             if ((value << 1) == 480 || (value << 1) == 512) {
2268*e5436536SAndroid Build Coastguard Worker               settings->userDownscaleFactor = 2;
2269*e5436536SAndroid Build Coastguard Worker             } else if ((value << 2) == 480 || (value << 2) == 512) {
2270*e5436536SAndroid Build Coastguard Worker               settings->userDownscaleFactor = 4;
2271*e5436536SAndroid Build Coastguard Worker             }
2272*e5436536SAndroid Build Coastguard Worker             settings->userFramelength = value;
2273*e5436536SAndroid Build Coastguard Worker             hAacEncoder->InitFlags |=
2274*e5436536SAndroid Build Coastguard Worker                 AACENC_INIT_CONFIG | AACENC_INIT_TRANSPORT;
2275*e5436536SAndroid Build Coastguard Worker             break;
2276*e5436536SAndroid Build Coastguard Worker           default:
2277*e5436536SAndroid Build Coastguard Worker             err = AACENC_INVALID_CONFIG;
2278*e5436536SAndroid Build Coastguard Worker             break;
2279*e5436536SAndroid Build Coastguard Worker         }
2280*e5436536SAndroid Build Coastguard Worker       }
2281*e5436536SAndroid Build Coastguard Worker       break;
2282*e5436536SAndroid Build Coastguard Worker     case AACENC_SBR_RATIO:
2283*e5436536SAndroid Build Coastguard Worker       if (settings->userSbrRatio != value) {
2284*e5436536SAndroid Build Coastguard Worker         if (!((value == 0) || (value == 1) || (value == 2))) {
2285*e5436536SAndroid Build Coastguard Worker           err = AACENC_INVALID_CONFIG;
2286*e5436536SAndroid Build Coastguard Worker           break;
2287*e5436536SAndroid Build Coastguard Worker         }
2288*e5436536SAndroid Build Coastguard Worker         settings->userSbrRatio = value;
2289*e5436536SAndroid Build Coastguard Worker         hAacEncoder->InitFlags |=
2290*e5436536SAndroid Build Coastguard Worker             AACENC_INIT_CONFIG | AACENC_INIT_STATES | AACENC_INIT_TRANSPORT;
2291*e5436536SAndroid Build Coastguard Worker       }
2292*e5436536SAndroid Build Coastguard Worker       break;
2293*e5436536SAndroid Build Coastguard Worker     case AACENC_SBR_MODE:
2294*e5436536SAndroid Build Coastguard Worker       if ((settings->userSbrEnabled != value) &&
2295*e5436536SAndroid Build Coastguard Worker           (NULL != hAacEncoder->hEnvEnc)) {
2296*e5436536SAndroid Build Coastguard Worker         settings->userSbrEnabled = value;
2297*e5436536SAndroid Build Coastguard Worker         hAacEncoder->InitFlags |=
2298*e5436536SAndroid Build Coastguard Worker             AACENC_INIT_CONFIG | AACENC_INIT_STATES | AACENC_INIT_TRANSPORT;
2299*e5436536SAndroid Build Coastguard Worker       }
2300*e5436536SAndroid Build Coastguard Worker       break;
2301*e5436536SAndroid Build Coastguard Worker     case AACENC_TRANSMUX:
2302*e5436536SAndroid Build Coastguard Worker       if (settings->userTpType != (TRANSPORT_TYPE)value) {
2303*e5436536SAndroid Build Coastguard Worker         TRANSPORT_TYPE type = (TRANSPORT_TYPE)value;
2304*e5436536SAndroid Build Coastguard Worker         UINT flags = hAacEncoder->CAPF_tpEnc;
2305*e5436536SAndroid Build Coastguard Worker 
2306*e5436536SAndroid Build Coastguard Worker         if (!(((type == TT_MP4_ADIF) && (flags & CAPF_ADIF)) ||
2307*e5436536SAndroid Build Coastguard Worker               ((type == TT_MP4_ADTS) && (flags & CAPF_ADTS)) ||
2308*e5436536SAndroid Build Coastguard Worker               ((type == TT_MP4_LATM_MCP0) &&
2309*e5436536SAndroid Build Coastguard Worker                ((flags & CAPF_LATM) && (flags & CAPF_RAWPACKETS))) ||
2310*e5436536SAndroid Build Coastguard Worker               ((type == TT_MP4_LATM_MCP1) &&
2311*e5436536SAndroid Build Coastguard Worker                ((flags & CAPF_LATM) && (flags & CAPF_RAWPACKETS))) ||
2312*e5436536SAndroid Build Coastguard Worker               ((type == TT_MP4_LOAS) && (flags & CAPF_LOAS)) ||
2313*e5436536SAndroid Build Coastguard Worker               ((type == TT_MP4_RAW) && (flags & CAPF_RAWPACKETS)))) {
2314*e5436536SAndroid Build Coastguard Worker           err = AACENC_INVALID_CONFIG;
2315*e5436536SAndroid Build Coastguard Worker           break;
2316*e5436536SAndroid Build Coastguard Worker         }
2317*e5436536SAndroid Build Coastguard Worker         settings->userTpType = (TRANSPORT_TYPE)value;
2318*e5436536SAndroid Build Coastguard Worker         hAacEncoder->InitFlags |= AACENC_INIT_TRANSPORT;
2319*e5436536SAndroid Build Coastguard Worker       }
2320*e5436536SAndroid Build Coastguard Worker       break;
2321*e5436536SAndroid Build Coastguard Worker     case AACENC_SIGNALING_MODE:
2322*e5436536SAndroid Build Coastguard Worker       if (settings->userTpSignaling != value) {
2323*e5436536SAndroid Build Coastguard Worker         if (!((value == 0) || (value == 1) || (value == 2))) {
2324*e5436536SAndroid Build Coastguard Worker           err = AACENC_INVALID_CONFIG;
2325*e5436536SAndroid Build Coastguard Worker           break;
2326*e5436536SAndroid Build Coastguard Worker         }
2327*e5436536SAndroid Build Coastguard Worker         settings->userTpSignaling = value;
2328*e5436536SAndroid Build Coastguard Worker         hAacEncoder->InitFlags |= AACENC_INIT_TRANSPORT;
2329*e5436536SAndroid Build Coastguard Worker       }
2330*e5436536SAndroid Build Coastguard Worker       break;
2331*e5436536SAndroid Build Coastguard Worker     case AACENC_PROTECTION:
2332*e5436536SAndroid Build Coastguard Worker       if (settings->userTpProtection != value) {
2333*e5436536SAndroid Build Coastguard Worker         if (!((value == 0) || (value == 1))) {
2334*e5436536SAndroid Build Coastguard Worker           err = AACENC_INVALID_CONFIG;
2335*e5436536SAndroid Build Coastguard Worker           break;
2336*e5436536SAndroid Build Coastguard Worker         }
2337*e5436536SAndroid Build Coastguard Worker         settings->userTpProtection = value;
2338*e5436536SAndroid Build Coastguard Worker         hAacEncoder->InitFlags |= AACENC_INIT_TRANSPORT;
2339*e5436536SAndroid Build Coastguard Worker       }
2340*e5436536SAndroid Build Coastguard Worker       break;
2341*e5436536SAndroid Build Coastguard Worker     case AACENC_HEADER_PERIOD:
2342*e5436536SAndroid Build Coastguard Worker       if (settings->userTpHeaderPeriod != value) {
2343*e5436536SAndroid Build Coastguard Worker         if (!(((INT)value >= 0) && (value <= 255))) {
2344*e5436536SAndroid Build Coastguard Worker           err = AACENC_INVALID_CONFIG;
2345*e5436536SAndroid Build Coastguard Worker           break;
2346*e5436536SAndroid Build Coastguard Worker         }
2347*e5436536SAndroid Build Coastguard Worker         settings->userTpHeaderPeriod = value;
2348*e5436536SAndroid Build Coastguard Worker         hAacEncoder->InitFlags |= AACENC_INIT_TRANSPORT;
2349*e5436536SAndroid Build Coastguard Worker       }
2350*e5436536SAndroid Build Coastguard Worker       break;
2351*e5436536SAndroid Build Coastguard Worker     case AACENC_AUDIOMUXVER:
2352*e5436536SAndroid Build Coastguard Worker       if (settings->userTpAmxv != value) {
2353*e5436536SAndroid Build Coastguard Worker         if (!((value == 0) || (value == 1) || (value == 2))) {
2354*e5436536SAndroid Build Coastguard Worker           err = AACENC_INVALID_CONFIG;
2355*e5436536SAndroid Build Coastguard Worker           break;
2356*e5436536SAndroid Build Coastguard Worker         }
2357*e5436536SAndroid Build Coastguard Worker         settings->userTpAmxv = value;
2358*e5436536SAndroid Build Coastguard Worker         hAacEncoder->InitFlags |= AACENC_INIT_TRANSPORT;
2359*e5436536SAndroid Build Coastguard Worker       }
2360*e5436536SAndroid Build Coastguard Worker       break;
2361*e5436536SAndroid Build Coastguard Worker     case AACENC_TPSUBFRAMES:
2362*e5436536SAndroid Build Coastguard Worker       if (settings->userTpNsubFrames != value) {
2363*e5436536SAndroid Build Coastguard Worker         if (!((value >= 1) && (value <= 4))) {
2364*e5436536SAndroid Build Coastguard Worker           err = AACENC_INVALID_CONFIG;
2365*e5436536SAndroid Build Coastguard Worker           break;
2366*e5436536SAndroid Build Coastguard Worker         }
2367*e5436536SAndroid Build Coastguard Worker         settings->userTpNsubFrames = value;
2368*e5436536SAndroid Build Coastguard Worker         hAacEncoder->InitFlags |= AACENC_INIT_TRANSPORT;
2369*e5436536SAndroid Build Coastguard Worker       }
2370*e5436536SAndroid Build Coastguard Worker       break;
2371*e5436536SAndroid Build Coastguard Worker     case AACENC_ANCILLARY_BITRATE:
2372*e5436536SAndroid Build Coastguard Worker       if (settings->userAncDataRate != value) {
2373*e5436536SAndroid Build Coastguard Worker         settings->userAncDataRate = value;
2374*e5436536SAndroid Build Coastguard Worker       }
2375*e5436536SAndroid Build Coastguard Worker       break;
2376*e5436536SAndroid Build Coastguard Worker     case AACENC_CONTROL_STATE:
2377*e5436536SAndroid Build Coastguard Worker       if (hAacEncoder->InitFlags != value) {
2378*e5436536SAndroid Build Coastguard Worker         if (value & AACENC_RESET_INBUFFER) {
2379*e5436536SAndroid Build Coastguard Worker           hAacEncoder->nSamplesRead = 0;
2380*e5436536SAndroid Build Coastguard Worker         }
2381*e5436536SAndroid Build Coastguard Worker         hAacEncoder->InitFlags = value;
2382*e5436536SAndroid Build Coastguard Worker       }
2383*e5436536SAndroid Build Coastguard Worker       break;
2384*e5436536SAndroid Build Coastguard Worker     case AACENC_METADATA_MODE:
2385*e5436536SAndroid Build Coastguard Worker       if ((UINT)settings->userMetaDataMode != value) {
2386*e5436536SAndroid Build Coastguard Worker         if (!(((INT)value >= 0) && ((INT)value <= 3))) {
2387*e5436536SAndroid Build Coastguard Worker           err = AACENC_INVALID_CONFIG;
2388*e5436536SAndroid Build Coastguard Worker           break;
2389*e5436536SAndroid Build Coastguard Worker         }
2390*e5436536SAndroid Build Coastguard Worker         settings->userMetaDataMode = value;
2391*e5436536SAndroid Build Coastguard Worker         hAacEncoder->InitFlags |= AACENC_INIT_CONFIG;
2392*e5436536SAndroid Build Coastguard Worker       }
2393*e5436536SAndroid Build Coastguard Worker       break;
2394*e5436536SAndroid Build Coastguard Worker     case AACENC_PEAK_BITRATE:
2395*e5436536SAndroid Build Coastguard Worker       if (settings->userPeakBitrate != value) {
2396*e5436536SAndroid Build Coastguard Worker         settings->userPeakBitrate = value;
2397*e5436536SAndroid Build Coastguard Worker         hAacEncoder->InitFlags |= AACENC_INIT_CONFIG | AACENC_INIT_TRANSPORT;
2398*e5436536SAndroid Build Coastguard Worker       }
2399*e5436536SAndroid Build Coastguard Worker       break;
2400*e5436536SAndroid Build Coastguard Worker     default:
2401*e5436536SAndroid Build Coastguard Worker       err = AACENC_UNSUPPORTED_PARAMETER;
2402*e5436536SAndroid Build Coastguard Worker       break;
2403*e5436536SAndroid Build Coastguard Worker   } /* switch(param) */
2404*e5436536SAndroid Build Coastguard Worker 
2405*e5436536SAndroid Build Coastguard Worker bail:
2406*e5436536SAndroid Build Coastguard Worker   return err;
2407*e5436536SAndroid Build Coastguard Worker }
2408*e5436536SAndroid Build Coastguard Worker 
aacEncoder_GetParam(const HANDLE_AACENCODER hAacEncoder,const AACENC_PARAM param)2409*e5436536SAndroid Build Coastguard Worker UINT aacEncoder_GetParam(const HANDLE_AACENCODER hAacEncoder,
2410*e5436536SAndroid Build Coastguard Worker                          const AACENC_PARAM param) {
2411*e5436536SAndroid Build Coastguard Worker   UINT value = 0;
2412*e5436536SAndroid Build Coastguard Worker   USER_PARAM *settings = &hAacEncoder->extParam;
2413*e5436536SAndroid Build Coastguard Worker 
2414*e5436536SAndroid Build Coastguard Worker   /* check encoder handle */
2415*e5436536SAndroid Build Coastguard Worker   if (hAacEncoder == NULL) {
2416*e5436536SAndroid Build Coastguard Worker     goto bail;
2417*e5436536SAndroid Build Coastguard Worker   }
2418*e5436536SAndroid Build Coastguard Worker 
2419*e5436536SAndroid Build Coastguard Worker   /* apply param value */
2420*e5436536SAndroid Build Coastguard Worker   switch (param) {
2421*e5436536SAndroid Build Coastguard Worker     case AACENC_AOT:
2422*e5436536SAndroid Build Coastguard Worker       value = (UINT)hAacEncoder->aacConfig.audioObjectType;
2423*e5436536SAndroid Build Coastguard Worker       break;
2424*e5436536SAndroid Build Coastguard Worker     case AACENC_BITRATE:
2425*e5436536SAndroid Build Coastguard Worker       switch (hAacEncoder->aacConfig.bitrateMode) {
2426*e5436536SAndroid Build Coastguard Worker         case AACENC_BR_MODE_CBR:
2427*e5436536SAndroid Build Coastguard Worker           value = (UINT)hAacEncoder->aacConfig.bitRate;
2428*e5436536SAndroid Build Coastguard Worker           break;
2429*e5436536SAndroid Build Coastguard Worker         default:
2430*e5436536SAndroid Build Coastguard Worker           value = (UINT)-1;
2431*e5436536SAndroid Build Coastguard Worker       }
2432*e5436536SAndroid Build Coastguard Worker       break;
2433*e5436536SAndroid Build Coastguard Worker     case AACENC_BITRATEMODE:
2434*e5436536SAndroid Build Coastguard Worker       value = (UINT)((hAacEncoder->aacConfig.bitrateMode != AACENC_BR_MODE_FF)
2435*e5436536SAndroid Build Coastguard Worker                          ? hAacEncoder->aacConfig.bitrateMode
2436*e5436536SAndroid Build Coastguard Worker                          : AACENC_BR_MODE_CBR);
2437*e5436536SAndroid Build Coastguard Worker       break;
2438*e5436536SAndroid Build Coastguard Worker     case AACENC_SAMPLERATE:
2439*e5436536SAndroid Build Coastguard Worker       value = (UINT)hAacEncoder->coderConfig.extSamplingRate;
2440*e5436536SAndroid Build Coastguard Worker       break;
2441*e5436536SAndroid Build Coastguard Worker     case AACENC_CHANNELMODE:
2442*e5436536SAndroid Build Coastguard Worker       if ((MODE_1 == hAacEncoder->aacConfig.channelMode) &&
2443*e5436536SAndroid Build Coastguard Worker           (hAacEncoder->aacConfig.syntaxFlags & AC_LD_MPS)) {
2444*e5436536SAndroid Build Coastguard Worker         value = MODE_212;
2445*e5436536SAndroid Build Coastguard Worker       } else {
2446*e5436536SAndroid Build Coastguard Worker         value = (UINT)hAacEncoder->aacConfig.channelMode;
2447*e5436536SAndroid Build Coastguard Worker       }
2448*e5436536SAndroid Build Coastguard Worker       break;
2449*e5436536SAndroid Build Coastguard Worker     case AACENC_BANDWIDTH:
2450*e5436536SAndroid Build Coastguard Worker       value = (UINT)hAacEncoder->aacConfig.bandWidth;
2451*e5436536SAndroid Build Coastguard Worker       break;
2452*e5436536SAndroid Build Coastguard Worker     case AACENC_CHANNELORDER:
2453*e5436536SAndroid Build Coastguard Worker       value = (UINT)hAacEncoder->aacConfig.channelOrder;
2454*e5436536SAndroid Build Coastguard Worker       break;
2455*e5436536SAndroid Build Coastguard Worker     case AACENC_AFTERBURNER:
2456*e5436536SAndroid Build Coastguard Worker       value = (UINT)hAacEncoder->aacConfig.useRequant;
2457*e5436536SAndroid Build Coastguard Worker       break;
2458*e5436536SAndroid Build Coastguard Worker     case AACENC_GRANULE_LENGTH:
2459*e5436536SAndroid Build Coastguard Worker       value = (UINT)hAacEncoder->aacConfig.framelength;
2460*e5436536SAndroid Build Coastguard Worker       break;
2461*e5436536SAndroid Build Coastguard Worker     case AACENC_SBR_RATIO:
2462*e5436536SAndroid Build Coastguard Worker       value = isSbrActive(&hAacEncoder->aacConfig)
2463*e5436536SAndroid Build Coastguard Worker                   ? hAacEncoder->aacConfig.sbrRatio
2464*e5436536SAndroid Build Coastguard Worker                   : 0;
2465*e5436536SAndroid Build Coastguard Worker       break;
2466*e5436536SAndroid Build Coastguard Worker     case AACENC_SBR_MODE:
2467*e5436536SAndroid Build Coastguard Worker       value =
2468*e5436536SAndroid Build Coastguard Worker           (UINT)(hAacEncoder->aacConfig.syntaxFlags & AC_SBR_PRESENT) ? 1 : 0;
2469*e5436536SAndroid Build Coastguard Worker       break;
2470*e5436536SAndroid Build Coastguard Worker     case AACENC_TRANSMUX:
2471*e5436536SAndroid Build Coastguard Worker       value = (UINT)settings->userTpType;
2472*e5436536SAndroid Build Coastguard Worker       break;
2473*e5436536SAndroid Build Coastguard Worker     case AACENC_SIGNALING_MODE:
2474*e5436536SAndroid Build Coastguard Worker       value = (UINT)getSbrSignalingMode(
2475*e5436536SAndroid Build Coastguard Worker           hAacEncoder->aacConfig.audioObjectType, settings->userTpType,
2476*e5436536SAndroid Build Coastguard Worker           settings->userTpSignaling, hAacEncoder->aacConfig.sbrRatio);
2477*e5436536SAndroid Build Coastguard Worker       break;
2478*e5436536SAndroid Build Coastguard Worker     case AACENC_PROTECTION:
2479*e5436536SAndroid Build Coastguard Worker       value = (UINT)settings->userTpProtection;
2480*e5436536SAndroid Build Coastguard Worker       break;
2481*e5436536SAndroid Build Coastguard Worker     case AACENC_HEADER_PERIOD:
2482*e5436536SAndroid Build Coastguard Worker       value = (UINT)hAacEncoder->coderConfig.headerPeriod;
2483*e5436536SAndroid Build Coastguard Worker       break;
2484*e5436536SAndroid Build Coastguard Worker     case AACENC_AUDIOMUXVER:
2485*e5436536SAndroid Build Coastguard Worker       value = (UINT)hAacEncoder->aacConfig.audioMuxVersion;
2486*e5436536SAndroid Build Coastguard Worker       break;
2487*e5436536SAndroid Build Coastguard Worker     case AACENC_TPSUBFRAMES:
2488*e5436536SAndroid Build Coastguard Worker       value = (UINT)settings->userTpNsubFrames;
2489*e5436536SAndroid Build Coastguard Worker       break;
2490*e5436536SAndroid Build Coastguard Worker     case AACENC_ANCILLARY_BITRATE:
2491*e5436536SAndroid Build Coastguard Worker       value = (UINT)hAacEncoder->aacConfig.anc_Rate;
2492*e5436536SAndroid Build Coastguard Worker       break;
2493*e5436536SAndroid Build Coastguard Worker     case AACENC_CONTROL_STATE:
2494*e5436536SAndroid Build Coastguard Worker       value = (UINT)hAacEncoder->InitFlags;
2495*e5436536SAndroid Build Coastguard Worker       break;
2496*e5436536SAndroid Build Coastguard Worker     case AACENC_METADATA_MODE:
2497*e5436536SAndroid Build Coastguard Worker       value = (hAacEncoder->metaDataAllowed == 0)
2498*e5436536SAndroid Build Coastguard Worker                   ? 0
2499*e5436536SAndroid Build Coastguard Worker                   : (UINT)settings->userMetaDataMode;
2500*e5436536SAndroid Build Coastguard Worker       break;
2501*e5436536SAndroid Build Coastguard Worker     case AACENC_PEAK_BITRATE:
2502*e5436536SAndroid Build Coastguard Worker       value = (UINT)-1; /* peak bitrate parameter is meaningless */
2503*e5436536SAndroid Build Coastguard Worker       if (((INT)hAacEncoder->extParam.userPeakBitrate != -1)) {
2504*e5436536SAndroid Build Coastguard Worker         value =
2505*e5436536SAndroid Build Coastguard Worker             (UINT)(fMax((INT)hAacEncoder->extParam.userPeakBitrate,
2506*e5436536SAndroid Build Coastguard Worker                         hAacEncoder->aacConfig
2507*e5436536SAndroid Build Coastguard Worker                             .bitRate)); /* peak bitrate parameter is in use */
2508*e5436536SAndroid Build Coastguard Worker       }
2509*e5436536SAndroid Build Coastguard Worker       break;
2510*e5436536SAndroid Build Coastguard Worker 
2511*e5436536SAndroid Build Coastguard Worker     default:
2512*e5436536SAndroid Build Coastguard Worker       // err = MPS_INVALID_PARAMETER;
2513*e5436536SAndroid Build Coastguard Worker       break;
2514*e5436536SAndroid Build Coastguard Worker   } /* switch(param) */
2515*e5436536SAndroid Build Coastguard Worker 
2516*e5436536SAndroid Build Coastguard Worker bail:
2517*e5436536SAndroid Build Coastguard Worker   return value;
2518*e5436536SAndroid Build Coastguard Worker }
2519*e5436536SAndroid Build Coastguard Worker 
aacEncInfo(const HANDLE_AACENCODER hAacEncoder,AACENC_InfoStruct * pInfo)2520*e5436536SAndroid Build Coastguard Worker AACENC_ERROR aacEncInfo(const HANDLE_AACENCODER hAacEncoder,
2521*e5436536SAndroid Build Coastguard Worker                         AACENC_InfoStruct *pInfo) {
2522*e5436536SAndroid Build Coastguard Worker   AACENC_ERROR err = AACENC_OK;
2523*e5436536SAndroid Build Coastguard Worker 
2524*e5436536SAndroid Build Coastguard Worker   if ((hAacEncoder == NULL) || (pInfo == NULL)) {
2525*e5436536SAndroid Build Coastguard Worker     err = AACENC_INVALID_HANDLE;
2526*e5436536SAndroid Build Coastguard Worker     goto bail;
2527*e5436536SAndroid Build Coastguard Worker   }
2528*e5436536SAndroid Build Coastguard Worker 
2529*e5436536SAndroid Build Coastguard Worker   FDKmemclear(pInfo, sizeof(AACENC_InfoStruct));
2530*e5436536SAndroid Build Coastguard Worker   pInfo->confSize = 64; /* pre-initialize */
2531*e5436536SAndroid Build Coastguard Worker 
2532*e5436536SAndroid Build Coastguard Worker   pInfo->maxOutBufBytes = ((hAacEncoder->nMaxAacChannels * 6144) + 7) >> 3;
2533*e5436536SAndroid Build Coastguard Worker   pInfo->maxAncBytes = hAacEncoder->aacConfig.maxAncBytesPerAU;
2534*e5436536SAndroid Build Coastguard Worker   pInfo->inBufFillLevel =
2535*e5436536SAndroid Build Coastguard Worker       hAacEncoder->nSamplesRead / hAacEncoder->extParam.nChannels;
2536*e5436536SAndroid Build Coastguard Worker   pInfo->inputChannels = hAacEncoder->extParam.nChannels;
2537*e5436536SAndroid Build Coastguard Worker   pInfo->frameLength =
2538*e5436536SAndroid Build Coastguard Worker       hAacEncoder->nSamplesToRead / hAacEncoder->extParam.nChannels;
2539*e5436536SAndroid Build Coastguard Worker   pInfo->nDelay = hAacEncoder->nDelay;
2540*e5436536SAndroid Build Coastguard Worker   pInfo->nDelayCore = hAacEncoder->nDelayCore;
2541*e5436536SAndroid Build Coastguard Worker 
2542*e5436536SAndroid Build Coastguard Worker   /* Get encoder configuration */
2543*e5436536SAndroid Build Coastguard Worker   if (aacEncGetConf(hAacEncoder, &pInfo->confSize, &pInfo->confBuf[0]) !=
2544*e5436536SAndroid Build Coastguard Worker       AAC_ENC_OK) {
2545*e5436536SAndroid Build Coastguard Worker     err = AACENC_INIT_ERROR;
2546*e5436536SAndroid Build Coastguard Worker     goto bail;
2547*e5436536SAndroid Build Coastguard Worker   }
2548*e5436536SAndroid Build Coastguard Worker bail:
2549*e5436536SAndroid Build Coastguard Worker   return err;
2550*e5436536SAndroid Build Coastguard Worker }
2551