xref: /aosp_15_r20/external/aac/libAACenc/src/metadata_main.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 - 2018 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):   V. Bacigalupo
98*e5436536SAndroid Build Coastguard Worker 
99*e5436536SAndroid Build Coastguard Worker    Description: Metadata Encoder library interface functions
100*e5436536SAndroid Build Coastguard Worker 
101*e5436536SAndroid Build Coastguard Worker *******************************************************************************/
102*e5436536SAndroid Build Coastguard Worker 
103*e5436536SAndroid Build Coastguard Worker #include "metadata_main.h"
104*e5436536SAndroid Build Coastguard Worker #include "metadata_compressor.h"
105*e5436536SAndroid Build Coastguard Worker #include "FDK_bitstream.h"
106*e5436536SAndroid Build Coastguard Worker #include "FDK_audio.h"
107*e5436536SAndroid Build Coastguard Worker #include "genericStds.h"
108*e5436536SAndroid Build Coastguard Worker 
109*e5436536SAndroid Build Coastguard Worker /*----------------- defines ----------------------*/
110*e5436536SAndroid Build Coastguard Worker #define MAX_DRC_BANDS (1 << 4)
111*e5436536SAndroid Build Coastguard Worker #define MAX_DRC_FRAMELEN (2 * 1024)
112*e5436536SAndroid Build Coastguard Worker #define MAX_DELAY_FRAMES (3)
113*e5436536SAndroid Build Coastguard Worker 
114*e5436536SAndroid Build Coastguard Worker /*--------------- structure definitions --------------------*/
115*e5436536SAndroid Build Coastguard Worker 
116*e5436536SAndroid Build Coastguard Worker typedef struct AAC_METADATA {
117*e5436536SAndroid Build Coastguard Worker   /* MPEG: Dynamic Range Control */
118*e5436536SAndroid Build Coastguard Worker   struct {
119*e5436536SAndroid Build Coastguard Worker     UCHAR prog_ref_level_present;
120*e5436536SAndroid Build Coastguard Worker     SCHAR prog_ref_level;
121*e5436536SAndroid Build Coastguard Worker 
122*e5436536SAndroid Build Coastguard Worker     UCHAR dyn_rng_sgn[MAX_DRC_BANDS];
123*e5436536SAndroid Build Coastguard Worker     UCHAR dyn_rng_ctl[MAX_DRC_BANDS];
124*e5436536SAndroid Build Coastguard Worker 
125*e5436536SAndroid Build Coastguard Worker     UCHAR drc_bands_present;
126*e5436536SAndroid Build Coastguard Worker     UCHAR drc_band_incr;
127*e5436536SAndroid Build Coastguard Worker     UCHAR drc_band_top[MAX_DRC_BANDS];
128*e5436536SAndroid Build Coastguard Worker     UCHAR drc_interpolation_scheme;
129*e5436536SAndroid Build Coastguard Worker     AACENC_METADATA_DRC_PROFILE drc_profile;
130*e5436536SAndroid Build Coastguard Worker     INT drc_TargetRefLevel; /* used for Limiter */
131*e5436536SAndroid Build Coastguard Worker 
132*e5436536SAndroid Build Coastguard Worker     /* excluded channels */
133*e5436536SAndroid Build Coastguard Worker     UCHAR excluded_chns_present;
134*e5436536SAndroid Build Coastguard Worker     UCHAR exclude_mask[2]; /* MAX_NUMBER_CHANNELS/8 */
135*e5436536SAndroid Build Coastguard Worker   } mpegDrc;
136*e5436536SAndroid Build Coastguard Worker 
137*e5436536SAndroid Build Coastguard Worker   /* ETSI: addtl ancillary data */
138*e5436536SAndroid Build Coastguard Worker   struct {
139*e5436536SAndroid Build Coastguard Worker     /* Heavy Compression */
140*e5436536SAndroid Build Coastguard Worker     UCHAR compression_on;    /* flag, if compression value should be written */
141*e5436536SAndroid Build Coastguard Worker     UCHAR compression_value; /* compression value */
142*e5436536SAndroid Build Coastguard Worker     AACENC_METADATA_DRC_PROFILE comp_profile;
143*e5436536SAndroid Build Coastguard Worker     INT comp_TargetRefLevel; /* used for Limiter */
144*e5436536SAndroid Build Coastguard Worker     INT timecode_coarse_status;
145*e5436536SAndroid Build Coastguard Worker     INT timecode_fine_status;
146*e5436536SAndroid Build Coastguard Worker 
147*e5436536SAndroid Build Coastguard Worker     UCHAR extAncDataStatus;
148*e5436536SAndroid Build Coastguard Worker 
149*e5436536SAndroid Build Coastguard Worker     struct {
150*e5436536SAndroid Build Coastguard Worker       UCHAR ext_downmix_lvl_status;
151*e5436536SAndroid Build Coastguard Worker       UCHAR ext_downmix_gain_status;
152*e5436536SAndroid Build Coastguard Worker       UCHAR ext_lfe_downmix_status;
153*e5436536SAndroid Build Coastguard Worker       UCHAR
154*e5436536SAndroid Build Coastguard Worker       ext_dmix_a_idx; /* extended downmix level (0..7, according to table)
155*e5436536SAndroid Build Coastguard Worker                        */
156*e5436536SAndroid Build Coastguard Worker       UCHAR
157*e5436536SAndroid Build Coastguard Worker       ext_dmix_b_idx; /* extended downmix level (0..7, according to table)
158*e5436536SAndroid Build Coastguard Worker                        */
159*e5436536SAndroid Build Coastguard Worker       UCHAR dmx_gain_5_sgn;
160*e5436536SAndroid Build Coastguard Worker       UCHAR dmx_gain_5_idx;
161*e5436536SAndroid Build Coastguard Worker       UCHAR dmx_gain_2_sgn;
162*e5436536SAndroid Build Coastguard Worker       UCHAR dmx_gain_2_idx;
163*e5436536SAndroid Build Coastguard Worker       UCHAR ext_dmix_lfe_idx; /* extended downmix level for lfe (0..15,
164*e5436536SAndroid Build Coastguard Worker                                  according to table) */
165*e5436536SAndroid Build Coastguard Worker 
166*e5436536SAndroid Build Coastguard Worker     } extAncData;
167*e5436536SAndroid Build Coastguard Worker 
168*e5436536SAndroid Build Coastguard Worker   } etsiAncData;
169*e5436536SAndroid Build Coastguard Worker 
170*e5436536SAndroid Build Coastguard Worker   SCHAR centerMixLevel; /* center downmix level (0...7, according to table) */
171*e5436536SAndroid Build Coastguard Worker   SCHAR
172*e5436536SAndroid Build Coastguard Worker   surroundMixLevel; /* surround downmix level (0...7, according to table) */
173*e5436536SAndroid Build Coastguard Worker   UCHAR WritePCEMixDwnIdx; /* flag */
174*e5436536SAndroid Build Coastguard Worker   UCHAR DmxLvl_On;         /* flag */
175*e5436536SAndroid Build Coastguard Worker 
176*e5436536SAndroid Build Coastguard Worker   UCHAR dolbySurroundMode;
177*e5436536SAndroid Build Coastguard Worker   UCHAR drcPresentationMode;
178*e5436536SAndroid Build Coastguard Worker 
179*e5436536SAndroid Build Coastguard Worker   UCHAR
180*e5436536SAndroid Build Coastguard Worker   metadataMode; /* indicate meta data mode in current frame (delay line) */
181*e5436536SAndroid Build Coastguard Worker 
182*e5436536SAndroid Build Coastguard Worker } AAC_METADATA;
183*e5436536SAndroid Build Coastguard Worker 
184*e5436536SAndroid Build Coastguard Worker typedef struct FDK_METADATA_ENCODER {
185*e5436536SAndroid Build Coastguard Worker   INT metadataMode;
186*e5436536SAndroid Build Coastguard Worker   HDRC_COMP hDrcComp;
187*e5436536SAndroid Build Coastguard Worker   AACENC_MetaData submittedMetaData;
188*e5436536SAndroid Build Coastguard Worker 
189*e5436536SAndroid Build Coastguard Worker   INT nAudioDataDelay; /* Additional delay to round up to next frame border (in
190*e5436536SAndroid Build Coastguard Worker                           samples) */
191*e5436536SAndroid Build Coastguard Worker   INT nMetaDataDelay;  /* Meta data delay (in frames) */
192*e5436536SAndroid Build Coastguard Worker   INT nChannels;
193*e5436536SAndroid Build Coastguard Worker   CHANNEL_MODE channelMode;
194*e5436536SAndroid Build Coastguard Worker 
195*e5436536SAndroid Build Coastguard Worker   INT_PCM* pAudioDelayBuffer;
196*e5436536SAndroid Build Coastguard Worker 
197*e5436536SAndroid Build Coastguard Worker   AAC_METADATA metaDataBuffer[MAX_DELAY_FRAMES];
198*e5436536SAndroid Build Coastguard Worker   INT metaDataDelayIdx;
199*e5436536SAndroid Build Coastguard Worker 
200*e5436536SAndroid Build Coastguard Worker   UCHAR drcInfoPayload[12];
201*e5436536SAndroid Build Coastguard Worker   UCHAR drcDsePayload[8];
202*e5436536SAndroid Build Coastguard Worker 
203*e5436536SAndroid Build Coastguard Worker   INT matrix_mixdown_idx;
204*e5436536SAndroid Build Coastguard Worker 
205*e5436536SAndroid Build Coastguard Worker   AACENC_EXT_PAYLOAD exPayload[2];
206*e5436536SAndroid Build Coastguard Worker   INT nExtensions;
207*e5436536SAndroid Build Coastguard Worker 
208*e5436536SAndroid Build Coastguard Worker   UINT maxChannels; /* Maximum number of audio channels to be supported. */
209*e5436536SAndroid Build Coastguard Worker 
210*e5436536SAndroid Build Coastguard Worker   INT finalizeMetaData;   /* Delay switch off by one frame and write default
211*e5436536SAndroid Build Coastguard Worker                              configuration to   finalize the metadata setup. */
212*e5436536SAndroid Build Coastguard Worker   INT initializeMetaData; /* Fill up delay line with first meta data info. This
213*e5436536SAndroid Build Coastguard Worker                              is required to have meta data already in first
214*e5436536SAndroid Build Coastguard Worker                              frame. */
215*e5436536SAndroid Build Coastguard Worker } FDK_METADATA_ENCODER;
216*e5436536SAndroid Build Coastguard Worker 
217*e5436536SAndroid Build Coastguard Worker /*---------------- constants -----------------------*/
218*e5436536SAndroid Build Coastguard Worker static const AACENC_MetaData defaultMetaDataSetup = {
219*e5436536SAndroid Build Coastguard Worker     AACENC_METADATA_DRC_NONE,        /* drc_profile */
220*e5436536SAndroid Build Coastguard Worker     AACENC_METADATA_DRC_NOT_PRESENT, /* comp_profile */
221*e5436536SAndroid Build Coastguard Worker     -(31 << 16),                     /* drc_TargetRefLevel */
222*e5436536SAndroid Build Coastguard Worker     -(23 << 16),                     /* comp_TargetRefLevel */
223*e5436536SAndroid Build Coastguard Worker     0,                               /* prog_ref_level_present */
224*e5436536SAndroid Build Coastguard Worker     -(23 << 16),                     /* prog_ref_level */
225*e5436536SAndroid Build Coastguard Worker     0,                               /* PCE_mixdown_idx_present */
226*e5436536SAndroid Build Coastguard Worker     0,                               /* ETSI_DmxLvl_present */
227*e5436536SAndroid Build Coastguard Worker     0,                               /* centerMixLevel */
228*e5436536SAndroid Build Coastguard Worker     0,                               /* surroundMixLevel */
229*e5436536SAndroid Build Coastguard Worker     0,                               /* dolbySurroundMode */
230*e5436536SAndroid Build Coastguard Worker     0,                               /* drcPresentationMode */
231*e5436536SAndroid Build Coastguard Worker     {0, 0, 0, 0, 0, 0, 0, 0, 0}      /* ExtMetaData */
232*e5436536SAndroid Build Coastguard Worker };
233*e5436536SAndroid Build Coastguard Worker 
234*e5436536SAndroid Build Coastguard Worker static const FIXP_DBL dmxTable[8] = {
235*e5436536SAndroid Build Coastguard Worker     ((FIXP_DBL)MAXVAL_DBL), FL2FXCONST_DBL(0.841f), FL2FXCONST_DBL(0.707f),
236*e5436536SAndroid Build Coastguard Worker     FL2FXCONST_DBL(0.596f), FL2FXCONST_DBL(0.500f), FL2FXCONST_DBL(0.422f),
237*e5436536SAndroid Build Coastguard Worker     FL2FXCONST_DBL(0.355f), FL2FXCONST_DBL(0.000f)};
238*e5436536SAndroid Build Coastguard Worker 
239*e5436536SAndroid Build Coastguard Worker #define FL2DMXLFE(a) FL2FXCONST_DBL((a) / (1 << LFE_LEV_SCALE))
240*e5436536SAndroid Build Coastguard Worker static const FIXP_DBL dmxLfeTable[16] = {
241*e5436536SAndroid Build Coastguard Worker     FL2DMXLFE(3.162f), FL2DMXLFE(2.000f), FL2DMXLFE(1.679f), FL2DMXLFE(1.413f),
242*e5436536SAndroid Build Coastguard Worker     FL2DMXLFE(1.189f), FL2DMXLFE(1.000f), FL2DMXLFE(0.841f), FL2DMXLFE(0.707f),
243*e5436536SAndroid Build Coastguard Worker     FL2DMXLFE(0.596f), FL2DMXLFE(0.500f), FL2DMXLFE(0.316f), FL2DMXLFE(0.178f),
244*e5436536SAndroid Build Coastguard Worker     FL2DMXLFE(0.100f), FL2DMXLFE(0.032f), FL2DMXLFE(0.010f), FL2DMXLFE(0.000f)};
245*e5436536SAndroid Build Coastguard Worker 
246*e5436536SAndroid Build Coastguard Worker static const UCHAR surmix2matrix_mixdown_idx[8] = {0, 0, 0, 1, 1, 2, 2, 3};
247*e5436536SAndroid Build Coastguard Worker 
248*e5436536SAndroid Build Coastguard Worker /*--------------- function declarations --------------------*/
249*e5436536SAndroid Build Coastguard Worker static FDK_METADATA_ERROR WriteMetadataPayload(
250*e5436536SAndroid Build Coastguard Worker     const HANDLE_FDK_METADATA_ENCODER hMetaData,
251*e5436536SAndroid Build Coastguard Worker     const AAC_METADATA* const pMetadata);
252*e5436536SAndroid Build Coastguard Worker 
253*e5436536SAndroid Build Coastguard Worker static INT WriteDynamicRangeInfoPayload(const AAC_METADATA* const pMetadata,
254*e5436536SAndroid Build Coastguard Worker                                         UCHAR* const pExtensionPayload);
255*e5436536SAndroid Build Coastguard Worker 
256*e5436536SAndroid Build Coastguard Worker static INT WriteEtsiAncillaryDataPayload(const AAC_METADATA* const pMetadata,
257*e5436536SAndroid Build Coastguard Worker                                          UCHAR* const pExtensionPayload);
258*e5436536SAndroid Build Coastguard Worker 
259*e5436536SAndroid Build Coastguard Worker static FDK_METADATA_ERROR CompensateAudioDelay(
260*e5436536SAndroid Build Coastguard Worker     HANDLE_FDK_METADATA_ENCODER hMetaDataEnc, INT_PCM* const pAudioSamples,
261*e5436536SAndroid Build Coastguard Worker     const UINT audioSamplesBufSize, const INT nAudioSamples);
262*e5436536SAndroid Build Coastguard Worker 
263*e5436536SAndroid Build Coastguard Worker static FDK_METADATA_ERROR LoadSubmittedMetadata(
264*e5436536SAndroid Build Coastguard Worker     const AACENC_MetaData* const hMetadata, const INT nChannels,
265*e5436536SAndroid Build Coastguard Worker     const INT metadataMode, AAC_METADATA* const pAacMetaData);
266*e5436536SAndroid Build Coastguard Worker 
267*e5436536SAndroid Build Coastguard Worker static FDK_METADATA_ERROR ProcessCompressor(AAC_METADATA* pMetadata,
268*e5436536SAndroid Build Coastguard Worker                                             HDRC_COMP hDrcComp,
269*e5436536SAndroid Build Coastguard Worker                                             const INT_PCM* const pSamples,
270*e5436536SAndroid Build Coastguard Worker                                             const UINT samplesBufSize,
271*e5436536SAndroid Build Coastguard Worker                                             const INT nSamples);
272*e5436536SAndroid Build Coastguard Worker 
273*e5436536SAndroid Build Coastguard Worker /*------------- function definitions ----------------*/
274*e5436536SAndroid Build Coastguard Worker 
convertProfile(AACENC_METADATA_DRC_PROFILE aacProfile)275*e5436536SAndroid Build Coastguard Worker static DRC_PROFILE convertProfile(AACENC_METADATA_DRC_PROFILE aacProfile) {
276*e5436536SAndroid Build Coastguard Worker   DRC_PROFILE drcProfile = DRC_NONE;
277*e5436536SAndroid Build Coastguard Worker 
278*e5436536SAndroid Build Coastguard Worker   switch (aacProfile) {
279*e5436536SAndroid Build Coastguard Worker     case AACENC_METADATA_DRC_NONE:
280*e5436536SAndroid Build Coastguard Worker       drcProfile = DRC_NONE;
281*e5436536SAndroid Build Coastguard Worker       break;
282*e5436536SAndroid Build Coastguard Worker     case AACENC_METADATA_DRC_FILMSTANDARD:
283*e5436536SAndroid Build Coastguard Worker       drcProfile = DRC_FILMSTANDARD;
284*e5436536SAndroid Build Coastguard Worker       break;
285*e5436536SAndroid Build Coastguard Worker     case AACENC_METADATA_DRC_FILMLIGHT:
286*e5436536SAndroid Build Coastguard Worker       drcProfile = DRC_FILMLIGHT;
287*e5436536SAndroid Build Coastguard Worker       break;
288*e5436536SAndroid Build Coastguard Worker     case AACENC_METADATA_DRC_MUSICSTANDARD:
289*e5436536SAndroid Build Coastguard Worker       drcProfile = DRC_MUSICSTANDARD;
290*e5436536SAndroid Build Coastguard Worker       break;
291*e5436536SAndroid Build Coastguard Worker     case AACENC_METADATA_DRC_MUSICLIGHT:
292*e5436536SAndroid Build Coastguard Worker       drcProfile = DRC_MUSICLIGHT;
293*e5436536SAndroid Build Coastguard Worker       break;
294*e5436536SAndroid Build Coastguard Worker     case AACENC_METADATA_DRC_SPEECH:
295*e5436536SAndroid Build Coastguard Worker       drcProfile = DRC_SPEECH;
296*e5436536SAndroid Build Coastguard Worker       break;
297*e5436536SAndroid Build Coastguard Worker     case AACENC_METADATA_DRC_NOT_PRESENT:
298*e5436536SAndroid Build Coastguard Worker       drcProfile = DRC_NOT_PRESENT;
299*e5436536SAndroid Build Coastguard Worker       break;
300*e5436536SAndroid Build Coastguard Worker     default:
301*e5436536SAndroid Build Coastguard Worker       drcProfile = DRC_NONE;
302*e5436536SAndroid Build Coastguard Worker       break;
303*e5436536SAndroid Build Coastguard Worker   }
304*e5436536SAndroid Build Coastguard Worker   return drcProfile;
305*e5436536SAndroid Build Coastguard Worker }
306*e5436536SAndroid Build Coastguard Worker 
307*e5436536SAndroid Build Coastguard Worker /* convert dialog normalization to program reference level */
308*e5436536SAndroid Build Coastguard Worker /* NOTE: this only is correct, if the decoder target level is set to -31dB for
309*e5436536SAndroid Build Coastguard Worker  * line mode / -20dB for RF mode */
dialnorm2progreflvl(const INT d)310*e5436536SAndroid Build Coastguard Worker static UCHAR dialnorm2progreflvl(const INT d) {
311*e5436536SAndroid Build Coastguard Worker   return ((UCHAR)fMax(0, fMin((-d + (1 << 13)) >> 14, 127)));
312*e5436536SAndroid Build Coastguard Worker }
313*e5436536SAndroid Build Coastguard Worker 
314*e5436536SAndroid Build Coastguard Worker /* convert program reference level to dialog normalization */
progreflvl2dialnorm(const UCHAR p)315*e5436536SAndroid Build Coastguard Worker static INT progreflvl2dialnorm(const UCHAR p) {
316*e5436536SAndroid Build Coastguard Worker   return -((INT)(p << (16 - 2)));
317*e5436536SAndroid Build Coastguard Worker }
318*e5436536SAndroid Build Coastguard Worker 
319*e5436536SAndroid Build Coastguard Worker /* encode downmix levels to Downmixing_levels_MPEG4 */
encodeDmxLvls(const SCHAR cmixlev,const SCHAR surmixlev)320*e5436536SAndroid Build Coastguard Worker static SCHAR encodeDmxLvls(const SCHAR cmixlev, const SCHAR surmixlev) {
321*e5436536SAndroid Build Coastguard Worker   SCHAR dmxLvls = 0;
322*e5436536SAndroid Build Coastguard Worker   dmxLvls |= 0x80 | (cmixlev << 4); /* center_mix_level_on */
323*e5436536SAndroid Build Coastguard Worker   dmxLvls |= 0x08 | surmixlev;      /* surround_mix_level_on */
324*e5436536SAndroid Build Coastguard Worker 
325*e5436536SAndroid Build Coastguard Worker   return dmxLvls;
326*e5436536SAndroid Build Coastguard Worker }
327*e5436536SAndroid Build Coastguard Worker 
328*e5436536SAndroid Build Coastguard Worker /* encode AAC DRC gain (ISO/IEC 14496-3:2005  4.5.2.7) */
encodeDynrng(INT gain,UCHAR * const dyn_rng_ctl,UCHAR * const dyn_rng_sgn)329*e5436536SAndroid Build Coastguard Worker static void encodeDynrng(INT gain, UCHAR* const dyn_rng_ctl,
330*e5436536SAndroid Build Coastguard Worker                          UCHAR* const dyn_rng_sgn) {
331*e5436536SAndroid Build Coastguard Worker   if (gain < 0) {
332*e5436536SAndroid Build Coastguard Worker     *dyn_rng_sgn = 1;
333*e5436536SAndroid Build Coastguard Worker     gain = -gain;
334*e5436536SAndroid Build Coastguard Worker   } else {
335*e5436536SAndroid Build Coastguard Worker     *dyn_rng_sgn = 0;
336*e5436536SAndroid Build Coastguard Worker   }
337*e5436536SAndroid Build Coastguard Worker   gain = fMin(gain, (127 << 14));
338*e5436536SAndroid Build Coastguard Worker 
339*e5436536SAndroid Build Coastguard Worker   *dyn_rng_ctl = (UCHAR)((gain + (1 << 13)) >> 14);
340*e5436536SAndroid Build Coastguard Worker }
341*e5436536SAndroid Build Coastguard Worker 
342*e5436536SAndroid Build Coastguard Worker /* decode AAC DRC gain (ISO/IEC 14496-3:2005  4.5.2.7) */
decodeDynrng(const UCHAR dyn_rng_ctl,const UCHAR dyn_rng_sgn)343*e5436536SAndroid Build Coastguard Worker static INT decodeDynrng(const UCHAR dyn_rng_ctl, const UCHAR dyn_rng_sgn) {
344*e5436536SAndroid Build Coastguard Worker   INT tmp = ((INT)dyn_rng_ctl << (16 - 2));
345*e5436536SAndroid Build Coastguard Worker   if (dyn_rng_sgn) tmp = -tmp;
346*e5436536SAndroid Build Coastguard Worker 
347*e5436536SAndroid Build Coastguard Worker   return tmp;
348*e5436536SAndroid Build Coastguard Worker }
349*e5436536SAndroid Build Coastguard Worker 
350*e5436536SAndroid Build Coastguard Worker /* encode AAC compression value (ETSI TS 101 154 page 99) */
encodeCompr(INT gain)351*e5436536SAndroid Build Coastguard Worker static UCHAR encodeCompr(INT gain) {
352*e5436536SAndroid Build Coastguard Worker   UCHAR x, y;
353*e5436536SAndroid Build Coastguard Worker   INT tmp;
354*e5436536SAndroid Build Coastguard Worker 
355*e5436536SAndroid Build Coastguard Worker   /* tmp = (int)((48.164f - gain) / 6.0206f * 15 + 0.5f); */
356*e5436536SAndroid Build Coastguard Worker   tmp = ((3156476 - gain) * 15 + 197283) / 394566;
357*e5436536SAndroid Build Coastguard Worker 
358*e5436536SAndroid Build Coastguard Worker   if (tmp >= 240) {
359*e5436536SAndroid Build Coastguard Worker     return 0xFF;
360*e5436536SAndroid Build Coastguard Worker   } else if (tmp < 0) {
361*e5436536SAndroid Build Coastguard Worker     return 0;
362*e5436536SAndroid Build Coastguard Worker   } else {
363*e5436536SAndroid Build Coastguard Worker     x = tmp / 15;
364*e5436536SAndroid Build Coastguard Worker     y = tmp % 15;
365*e5436536SAndroid Build Coastguard Worker   }
366*e5436536SAndroid Build Coastguard Worker 
367*e5436536SAndroid Build Coastguard Worker   return (x << 4) | y;
368*e5436536SAndroid Build Coastguard Worker }
369*e5436536SAndroid Build Coastguard Worker 
370*e5436536SAndroid Build Coastguard Worker /* decode AAC compression value (ETSI TS 101 154 page 99) */
decodeCompr(const UCHAR compr)371*e5436536SAndroid Build Coastguard Worker static INT decodeCompr(const UCHAR compr) {
372*e5436536SAndroid Build Coastguard Worker   INT gain;
373*e5436536SAndroid Build Coastguard Worker   SCHAR x = compr >> 4;     /* 4 MSB of compr */
374*e5436536SAndroid Build Coastguard Worker   UCHAR y = (compr & 0x0F); /* 4 LSB of compr */
375*e5436536SAndroid Build Coastguard Worker 
376*e5436536SAndroid Build Coastguard Worker   /* gain = (INT)((48.164f - 6.0206f * x - 0.4014f * y) ); */
377*e5436536SAndroid Build Coastguard Worker   gain = (INT)(
378*e5436536SAndroid Build Coastguard Worker       scaleValue((FIXP_DBL)(((LONG)FL2FXCONST_DBL(6.0206f / 128.f) * (8 - x) -
379*e5436536SAndroid Build Coastguard Worker                              (LONG)FL2FXCONST_DBL(0.4014f / 128.f) * y)),
380*e5436536SAndroid Build Coastguard Worker                  -(DFRACT_BITS - 1 - 7 - 16)));
381*e5436536SAndroid Build Coastguard Worker 
382*e5436536SAndroid Build Coastguard Worker   return gain;
383*e5436536SAndroid Build Coastguard Worker }
384*e5436536SAndroid Build Coastguard Worker 
FDK_MetadataEnc_Open(HANDLE_FDK_METADATA_ENCODER * phMetaData,const UINT maxChannels)385*e5436536SAndroid Build Coastguard Worker FDK_METADATA_ERROR FDK_MetadataEnc_Open(HANDLE_FDK_METADATA_ENCODER* phMetaData,
386*e5436536SAndroid Build Coastguard Worker                                         const UINT maxChannels) {
387*e5436536SAndroid Build Coastguard Worker   FDK_METADATA_ERROR err = METADATA_OK;
388*e5436536SAndroid Build Coastguard Worker   HANDLE_FDK_METADATA_ENCODER hMetaData = NULL;
389*e5436536SAndroid Build Coastguard Worker 
390*e5436536SAndroid Build Coastguard Worker   if (phMetaData == NULL) {
391*e5436536SAndroid Build Coastguard Worker     err = METADATA_INVALID_HANDLE;
392*e5436536SAndroid Build Coastguard Worker     goto bail;
393*e5436536SAndroid Build Coastguard Worker   }
394*e5436536SAndroid Build Coastguard Worker 
395*e5436536SAndroid Build Coastguard Worker   /* allocate memory */
396*e5436536SAndroid Build Coastguard Worker   if (NULL == (hMetaData = (HANDLE_FDK_METADATA_ENCODER)FDKcalloc(
397*e5436536SAndroid Build Coastguard Worker                    1, sizeof(FDK_METADATA_ENCODER)))) {
398*e5436536SAndroid Build Coastguard Worker     err = METADATA_MEMORY_ERROR;
399*e5436536SAndroid Build Coastguard Worker     goto bail;
400*e5436536SAndroid Build Coastguard Worker   }
401*e5436536SAndroid Build Coastguard Worker   FDKmemclear(hMetaData, sizeof(FDK_METADATA_ENCODER));
402*e5436536SAndroid Build Coastguard Worker 
403*e5436536SAndroid Build Coastguard Worker   if (NULL == (hMetaData->pAudioDelayBuffer = (INT_PCM*)FDKcalloc(
404*e5436536SAndroid Build Coastguard Worker                    maxChannels * MAX_DRC_FRAMELEN, sizeof(INT_PCM)))) {
405*e5436536SAndroid Build Coastguard Worker     err = METADATA_MEMORY_ERROR;
406*e5436536SAndroid Build Coastguard Worker     goto bail;
407*e5436536SAndroid Build Coastguard Worker   }
408*e5436536SAndroid Build Coastguard Worker   FDKmemclear(hMetaData->pAudioDelayBuffer,
409*e5436536SAndroid Build Coastguard Worker               maxChannels * MAX_DRC_FRAMELEN * sizeof(INT_PCM));
410*e5436536SAndroid Build Coastguard Worker   hMetaData->maxChannels = maxChannels;
411*e5436536SAndroid Build Coastguard Worker 
412*e5436536SAndroid Build Coastguard Worker   /* Allocate DRC Compressor. */
413*e5436536SAndroid Build Coastguard Worker   if (FDK_DRC_Generator_Open(&hMetaData->hDrcComp) != 0) {
414*e5436536SAndroid Build Coastguard Worker     err = METADATA_MEMORY_ERROR;
415*e5436536SAndroid Build Coastguard Worker     goto bail;
416*e5436536SAndroid Build Coastguard Worker   }
417*e5436536SAndroid Build Coastguard Worker   hMetaData->channelMode = MODE_UNKNOWN;
418*e5436536SAndroid Build Coastguard Worker 
419*e5436536SAndroid Build Coastguard Worker   /* Return metadata instance */
420*e5436536SAndroid Build Coastguard Worker   *phMetaData = hMetaData;
421*e5436536SAndroid Build Coastguard Worker 
422*e5436536SAndroid Build Coastguard Worker   return err;
423*e5436536SAndroid Build Coastguard Worker 
424*e5436536SAndroid Build Coastguard Worker bail:
425*e5436536SAndroid Build Coastguard Worker   FDK_MetadataEnc_Close(&hMetaData);
426*e5436536SAndroid Build Coastguard Worker   return err;
427*e5436536SAndroid Build Coastguard Worker }
428*e5436536SAndroid Build Coastguard Worker 
FDK_MetadataEnc_Close(HANDLE_FDK_METADATA_ENCODER * phMetaData)429*e5436536SAndroid Build Coastguard Worker FDK_METADATA_ERROR FDK_MetadataEnc_Close(
430*e5436536SAndroid Build Coastguard Worker     HANDLE_FDK_METADATA_ENCODER* phMetaData) {
431*e5436536SAndroid Build Coastguard Worker   FDK_METADATA_ERROR err = METADATA_OK;
432*e5436536SAndroid Build Coastguard Worker 
433*e5436536SAndroid Build Coastguard Worker   if (phMetaData == NULL) {
434*e5436536SAndroid Build Coastguard Worker     err = METADATA_INVALID_HANDLE;
435*e5436536SAndroid Build Coastguard Worker     goto bail;
436*e5436536SAndroid Build Coastguard Worker   }
437*e5436536SAndroid Build Coastguard Worker 
438*e5436536SAndroid Build Coastguard Worker   if (*phMetaData != NULL) {
439*e5436536SAndroid Build Coastguard Worker     FDK_DRC_Generator_Close(&(*phMetaData)->hDrcComp);
440*e5436536SAndroid Build Coastguard Worker     FDKfree((*phMetaData)->pAudioDelayBuffer);
441*e5436536SAndroid Build Coastguard Worker     FDKfree(*phMetaData);
442*e5436536SAndroid Build Coastguard Worker     *phMetaData = NULL;
443*e5436536SAndroid Build Coastguard Worker   }
444*e5436536SAndroid Build Coastguard Worker bail:
445*e5436536SAndroid Build Coastguard Worker   return err;
446*e5436536SAndroid Build Coastguard Worker }
447*e5436536SAndroid Build Coastguard Worker 
FDK_MetadataEnc_Init(HANDLE_FDK_METADATA_ENCODER hMetaData,const INT resetStates,const INT metadataMode,const INT audioDelay,const UINT frameLength,const UINT sampleRate,const UINT nChannels,const CHANNEL_MODE channelMode,const CHANNEL_ORDER channelOrder)448*e5436536SAndroid Build Coastguard Worker FDK_METADATA_ERROR FDK_MetadataEnc_Init(
449*e5436536SAndroid Build Coastguard Worker     HANDLE_FDK_METADATA_ENCODER hMetaData, const INT resetStates,
450*e5436536SAndroid Build Coastguard Worker     const INT metadataMode, const INT audioDelay, const UINT frameLength,
451*e5436536SAndroid Build Coastguard Worker     const UINT sampleRate, const UINT nChannels, const CHANNEL_MODE channelMode,
452*e5436536SAndroid Build Coastguard Worker     const CHANNEL_ORDER channelOrder) {
453*e5436536SAndroid Build Coastguard Worker   FDK_METADATA_ERROR err = METADATA_OK;
454*e5436536SAndroid Build Coastguard Worker   int i, nFrames, delay;
455*e5436536SAndroid Build Coastguard Worker 
456*e5436536SAndroid Build Coastguard Worker   if (hMetaData == NULL) {
457*e5436536SAndroid Build Coastguard Worker     err = METADATA_INVALID_HANDLE;
458*e5436536SAndroid Build Coastguard Worker     goto bail;
459*e5436536SAndroid Build Coastguard Worker   }
460*e5436536SAndroid Build Coastguard Worker 
461*e5436536SAndroid Build Coastguard Worker   /* Determine values for delay compensation. */
462*e5436536SAndroid Build Coastguard Worker   for (nFrames = 0, delay = audioDelay - (INT)frameLength; delay > 0;
463*e5436536SAndroid Build Coastguard Worker        delay -= (INT)frameLength, nFrames++)
464*e5436536SAndroid Build Coastguard Worker     ;
465*e5436536SAndroid Build Coastguard Worker 
466*e5436536SAndroid Build Coastguard Worker   if ((nChannels > (8)) || (nChannels > hMetaData->maxChannels) ||
467*e5436536SAndroid Build Coastguard Worker       ((-delay) > MAX_DRC_FRAMELEN) || nFrames >= MAX_DELAY_FRAMES) {
468*e5436536SAndroid Build Coastguard Worker     err = METADATA_INIT_ERROR;
469*e5436536SAndroid Build Coastguard Worker     goto bail;
470*e5436536SAndroid Build Coastguard Worker   }
471*e5436536SAndroid Build Coastguard Worker 
472*e5436536SAndroid Build Coastguard Worker   /* Initialize with default setup. */
473*e5436536SAndroid Build Coastguard Worker   FDKmemcpy(&hMetaData->submittedMetaData, &defaultMetaDataSetup,
474*e5436536SAndroid Build Coastguard Worker             sizeof(AACENC_MetaData));
475*e5436536SAndroid Build Coastguard Worker 
476*e5436536SAndroid Build Coastguard Worker   hMetaData->finalizeMetaData =
477*e5436536SAndroid Build Coastguard Worker       0; /* finalize meta data only while on/off switching, else disabled */
478*e5436536SAndroid Build Coastguard Worker   hMetaData->initializeMetaData =
479*e5436536SAndroid Build Coastguard Worker       0; /* fill up meta data delay line only at a reset otherwise disabled */
480*e5436536SAndroid Build Coastguard Worker 
481*e5436536SAndroid Build Coastguard Worker   /* Reset delay lines. */
482*e5436536SAndroid Build Coastguard Worker   if (resetStates || (hMetaData->nAudioDataDelay != -delay) ||
483*e5436536SAndroid Build Coastguard Worker       (hMetaData->channelMode != channelMode)) {
484*e5436536SAndroid Build Coastguard Worker     if (resetStates || (hMetaData->channelMode == MODE_UNKNOWN)) {
485*e5436536SAndroid Build Coastguard Worker       /* clear delay buffer */
486*e5436536SAndroid Build Coastguard Worker       FDKmemclear(hMetaData->pAudioDelayBuffer,
487*e5436536SAndroid Build Coastguard Worker                   hMetaData->maxChannels * MAX_DRC_FRAMELEN * sizeof(INT_PCM));
488*e5436536SAndroid Build Coastguard Worker     } else {
489*e5436536SAndroid Build Coastguard Worker       /* if possible, keep static audio channels for seamless channel
490*e5436536SAndroid Build Coastguard Worker        * reconfiguration */
491*e5436536SAndroid Build Coastguard Worker       FDK_channelMapDescr mapDescrPrev, mapDescr;
492*e5436536SAndroid Build Coastguard Worker       int c, src[2] = {-1, -1}, dst[2] = {-1, -1};
493*e5436536SAndroid Build Coastguard Worker 
494*e5436536SAndroid Build Coastguard Worker       FDK_chMapDescr_init(&mapDescrPrev, NULL, 0,
495*e5436536SAndroid Build Coastguard Worker                           (channelOrder == CH_ORDER_MPEG) ? 1 : 0);
496*e5436536SAndroid Build Coastguard Worker       FDK_chMapDescr_init(&mapDescr, NULL, 0,
497*e5436536SAndroid Build Coastguard Worker                           (channelOrder == CH_ORDER_MPEG) ? 1 : 0);
498*e5436536SAndroid Build Coastguard Worker 
499*e5436536SAndroid Build Coastguard Worker       switch (channelMode) {
500*e5436536SAndroid Build Coastguard Worker         case MODE_1:
501*e5436536SAndroid Build Coastguard Worker           if ((INT)nChannels != 2) {
502*e5436536SAndroid Build Coastguard Worker             /* preserve center channel */
503*e5436536SAndroid Build Coastguard Worker             src[0] = FDK_chMapDescr_getMapValue(&mapDescrPrev, 0,
504*e5436536SAndroid Build Coastguard Worker                                                 hMetaData->channelMode);
505*e5436536SAndroid Build Coastguard Worker             dst[0] = FDK_chMapDescr_getMapValue(&mapDescr, 0, channelMode);
506*e5436536SAndroid Build Coastguard Worker           }
507*e5436536SAndroid Build Coastguard Worker           break;
508*e5436536SAndroid Build Coastguard Worker         case MODE_2:
509*e5436536SAndroid Build Coastguard Worker         case MODE_1_2:
510*e5436536SAndroid Build Coastguard Worker         case MODE_1_2_1:
511*e5436536SAndroid Build Coastguard Worker         case MODE_1_2_2:
512*e5436536SAndroid Build Coastguard Worker         case MODE_1_2_2_1:
513*e5436536SAndroid Build Coastguard Worker           if (hMetaData->nChannels >= 2) {
514*e5436536SAndroid Build Coastguard Worker             /* preserve left/right channel */
515*e5436536SAndroid Build Coastguard Worker             src[0] = FDK_chMapDescr_getMapValue(
516*e5436536SAndroid Build Coastguard Worker                 &mapDescrPrev, ((hMetaData->channelMode == 2) ? 0 : 1),
517*e5436536SAndroid Build Coastguard Worker                 hMetaData->channelMode);
518*e5436536SAndroid Build Coastguard Worker             src[1] = FDK_chMapDescr_getMapValue(
519*e5436536SAndroid Build Coastguard Worker                 &mapDescrPrev, ((hMetaData->channelMode == 2) ? 1 : 2),
520*e5436536SAndroid Build Coastguard Worker                 hMetaData->channelMode);
521*e5436536SAndroid Build Coastguard Worker             dst[0] = FDK_chMapDescr_getMapValue(
522*e5436536SAndroid Build Coastguard Worker                 &mapDescr, ((channelMode == 2) ? 0 : 1), channelMode);
523*e5436536SAndroid Build Coastguard Worker             dst[1] = FDK_chMapDescr_getMapValue(
524*e5436536SAndroid Build Coastguard Worker                 &mapDescr, ((channelMode == 2) ? 1 : 2), channelMode);
525*e5436536SAndroid Build Coastguard Worker           }
526*e5436536SAndroid Build Coastguard Worker           break;
527*e5436536SAndroid Build Coastguard Worker         default:;
528*e5436536SAndroid Build Coastguard Worker       }
529*e5436536SAndroid Build Coastguard Worker       C_ALLOC_SCRATCH_START(scratch_audioDelayBuffer, INT_PCM, (8));
530*e5436536SAndroid Build Coastguard Worker       FDKmemclear(scratch_audioDelayBuffer, (8) * sizeof(INT_PCM));
531*e5436536SAndroid Build Coastguard Worker 
532*e5436536SAndroid Build Coastguard Worker       i = (hMetaData->nChannels > (INT)nChannels)
533*e5436536SAndroid Build Coastguard Worker               ? 0
534*e5436536SAndroid Build Coastguard Worker               : hMetaData->nAudioDataDelay - 1;
535*e5436536SAndroid Build Coastguard Worker       do {
536*e5436536SAndroid Build Coastguard Worker         for (c = 0; c < 2; c++) {
537*e5436536SAndroid Build Coastguard Worker           if (src[c] != -1 && dst[c] != -1) {
538*e5436536SAndroid Build Coastguard Worker             scratch_audioDelayBuffer[dst[c]] =
539*e5436536SAndroid Build Coastguard Worker                 hMetaData->pAudioDelayBuffer[i * hMetaData->nChannels + src[c]];
540*e5436536SAndroid Build Coastguard Worker           }
541*e5436536SAndroid Build Coastguard Worker         }
542*e5436536SAndroid Build Coastguard Worker         FDKmemcpy(&hMetaData->pAudioDelayBuffer[i * nChannels],
543*e5436536SAndroid Build Coastguard Worker                   scratch_audioDelayBuffer, nChannels * sizeof(INT_PCM));
544*e5436536SAndroid Build Coastguard Worker         i += (hMetaData->nChannels > (INT)nChannels) ? 1 : -1;
545*e5436536SAndroid Build Coastguard Worker       } while ((i < hMetaData->nAudioDataDelay) && (i >= 0));
546*e5436536SAndroid Build Coastguard Worker 
547*e5436536SAndroid Build Coastguard Worker       C_ALLOC_SCRATCH_END(scratch_audioDelayBuffer, INT_PCM, (8));
548*e5436536SAndroid Build Coastguard Worker     }
549*e5436536SAndroid Build Coastguard Worker     FDKmemclear(hMetaData->metaDataBuffer, sizeof(hMetaData->metaDataBuffer));
550*e5436536SAndroid Build Coastguard Worker     hMetaData->metaDataDelayIdx = 0;
551*e5436536SAndroid Build Coastguard Worker     hMetaData->initializeMetaData =
552*e5436536SAndroid Build Coastguard Worker         1; /* fill up delay line with first meta data info */
553*e5436536SAndroid Build Coastguard Worker   } else {
554*e5436536SAndroid Build Coastguard Worker     /* Enable meta data. */
555*e5436536SAndroid Build Coastguard Worker     if ((hMetaData->metadataMode == 0) && (metadataMode != 0)) {
556*e5436536SAndroid Build Coastguard Worker       /* disable meta data in all delay lines */
557*e5436536SAndroid Build Coastguard Worker       for (i = 0;
558*e5436536SAndroid Build Coastguard Worker            i < (int)(sizeof(hMetaData->metaDataBuffer) / sizeof(AAC_METADATA));
559*e5436536SAndroid Build Coastguard Worker            i++) {
560*e5436536SAndroid Build Coastguard Worker         LoadSubmittedMetadata(&hMetaData->submittedMetaData, nChannels, 0,
561*e5436536SAndroid Build Coastguard Worker                               &hMetaData->metaDataBuffer[i]);
562*e5436536SAndroid Build Coastguard Worker       }
563*e5436536SAndroid Build Coastguard Worker     }
564*e5436536SAndroid Build Coastguard Worker 
565*e5436536SAndroid Build Coastguard Worker     /* Disable meta data.*/
566*e5436536SAndroid Build Coastguard Worker     if ((hMetaData->metadataMode != 0) && (metadataMode == 0)) {
567*e5436536SAndroid Build Coastguard Worker       hMetaData->finalizeMetaData = hMetaData->metadataMode;
568*e5436536SAndroid Build Coastguard Worker     }
569*e5436536SAndroid Build Coastguard Worker   }
570*e5436536SAndroid Build Coastguard Worker 
571*e5436536SAndroid Build Coastguard Worker   /* Initialize delay. */
572*e5436536SAndroid Build Coastguard Worker   hMetaData->nAudioDataDelay = -delay;
573*e5436536SAndroid Build Coastguard Worker   hMetaData->nMetaDataDelay = nFrames;
574*e5436536SAndroid Build Coastguard Worker   hMetaData->nChannels = nChannels;
575*e5436536SAndroid Build Coastguard Worker   hMetaData->channelMode = channelMode;
576*e5436536SAndroid Build Coastguard Worker   hMetaData->metadataMode = metadataMode;
577*e5436536SAndroid Build Coastguard Worker 
578*e5436536SAndroid Build Coastguard Worker   /* Initialize compressor. */
579*e5436536SAndroid Build Coastguard Worker   if ((metadataMode == 1) || (metadataMode == 2)) {
580*e5436536SAndroid Build Coastguard Worker     if (FDK_DRC_Generator_Initialize(hMetaData->hDrcComp, DRC_NONE, DRC_NONE,
581*e5436536SAndroid Build Coastguard Worker                                      frameLength, sampleRate, channelMode,
582*e5436536SAndroid Build Coastguard Worker                                      channelOrder, 1) != 0) {
583*e5436536SAndroid Build Coastguard Worker       err = METADATA_INIT_ERROR;
584*e5436536SAndroid Build Coastguard Worker     }
585*e5436536SAndroid Build Coastguard Worker   }
586*e5436536SAndroid Build Coastguard Worker bail:
587*e5436536SAndroid Build Coastguard Worker   return err;
588*e5436536SAndroid Build Coastguard Worker }
589*e5436536SAndroid Build Coastguard Worker 
ProcessCompressor(AAC_METADATA * pMetadata,HDRC_COMP hDrcComp,const INT_PCM * const pSamples,const UINT samplesBufSize,const INT nSamples)590*e5436536SAndroid Build Coastguard Worker static FDK_METADATA_ERROR ProcessCompressor(AAC_METADATA* pMetadata,
591*e5436536SAndroid Build Coastguard Worker                                             HDRC_COMP hDrcComp,
592*e5436536SAndroid Build Coastguard Worker                                             const INT_PCM* const pSamples,
593*e5436536SAndroid Build Coastguard Worker                                             const UINT samplesBufSize,
594*e5436536SAndroid Build Coastguard Worker                                             const INT nSamples) {
595*e5436536SAndroid Build Coastguard Worker   FDK_METADATA_ERROR err = METADATA_OK;
596*e5436536SAndroid Build Coastguard Worker 
597*e5436536SAndroid Build Coastguard Worker   INT dynrng, compr;
598*e5436536SAndroid Build Coastguard Worker   INT dmxGain5, dmxGain2;
599*e5436536SAndroid Build Coastguard Worker   DRC_PROFILE profileDrc;
600*e5436536SAndroid Build Coastguard Worker   DRC_PROFILE profileComp;
601*e5436536SAndroid Build Coastguard Worker 
602*e5436536SAndroid Build Coastguard Worker   if ((pMetadata == NULL) || (hDrcComp == NULL)) {
603*e5436536SAndroid Build Coastguard Worker     err = METADATA_INVALID_HANDLE;
604*e5436536SAndroid Build Coastguard Worker     return err;
605*e5436536SAndroid Build Coastguard Worker   }
606*e5436536SAndroid Build Coastguard Worker 
607*e5436536SAndroid Build Coastguard Worker   profileDrc = convertProfile(pMetadata->mpegDrc.drc_profile);
608*e5436536SAndroid Build Coastguard Worker   profileComp = convertProfile(pMetadata->etsiAncData.comp_profile);
609*e5436536SAndroid Build Coastguard Worker 
610*e5436536SAndroid Build Coastguard Worker   /* first, check if profile is same as last frame
611*e5436536SAndroid Build Coastguard Worker    * otherwise, update setup */
612*e5436536SAndroid Build Coastguard Worker   if ((profileDrc != FDK_DRC_Generator_getDrcProfile(hDrcComp)) ||
613*e5436536SAndroid Build Coastguard Worker       (profileComp != FDK_DRC_Generator_getCompProfile(hDrcComp))) {
614*e5436536SAndroid Build Coastguard Worker     FDK_DRC_Generator_setDrcProfile(hDrcComp, profileDrc, profileComp);
615*e5436536SAndroid Build Coastguard Worker   }
616*e5436536SAndroid Build Coastguard Worker 
617*e5436536SAndroid Build Coastguard Worker   /* Sanity check */
618*e5436536SAndroid Build Coastguard Worker   if (profileComp == DRC_NONE) {
619*e5436536SAndroid Build Coastguard Worker     pMetadata->etsiAncData.compression_value = 0x80; /* to ensure no external
620*e5436536SAndroid Build Coastguard Worker                                                         values will be written
621*e5436536SAndroid Build Coastguard Worker                                                         if not configured */
622*e5436536SAndroid Build Coastguard Worker   }
623*e5436536SAndroid Build Coastguard Worker 
624*e5436536SAndroid Build Coastguard Worker   /* in case of embedding external values, copy this now (limiter may overwrite
625*e5436536SAndroid Build Coastguard Worker    * them) */
626*e5436536SAndroid Build Coastguard Worker   dynrng = decodeDynrng(pMetadata->mpegDrc.dyn_rng_ctl[0],
627*e5436536SAndroid Build Coastguard Worker                         pMetadata->mpegDrc.dyn_rng_sgn[0]);
628*e5436536SAndroid Build Coastguard Worker   compr = decodeCompr(pMetadata->etsiAncData.compression_value);
629*e5436536SAndroid Build Coastguard Worker 
630*e5436536SAndroid Build Coastguard Worker   dmxGain5 = decodeDynrng(pMetadata->etsiAncData.extAncData.dmx_gain_5_idx,
631*e5436536SAndroid Build Coastguard Worker                           pMetadata->etsiAncData.extAncData.dmx_gain_5_sgn);
632*e5436536SAndroid Build Coastguard Worker   dmxGain2 = decodeDynrng(pMetadata->etsiAncData.extAncData.dmx_gain_2_idx,
633*e5436536SAndroid Build Coastguard Worker                           pMetadata->etsiAncData.extAncData.dmx_gain_2_sgn);
634*e5436536SAndroid Build Coastguard Worker 
635*e5436536SAndroid Build Coastguard Worker   /* Call compressor */
636*e5436536SAndroid Build Coastguard Worker   if (FDK_DRC_Generator_Calc(
637*e5436536SAndroid Build Coastguard Worker           hDrcComp, pSamples, samplesBufSize,
638*e5436536SAndroid Build Coastguard Worker           progreflvl2dialnorm(pMetadata->mpegDrc.prog_ref_level),
639*e5436536SAndroid Build Coastguard Worker           pMetadata->mpegDrc.drc_TargetRefLevel,
640*e5436536SAndroid Build Coastguard Worker           pMetadata->etsiAncData.comp_TargetRefLevel,
641*e5436536SAndroid Build Coastguard Worker           dmxTable[pMetadata->centerMixLevel],
642*e5436536SAndroid Build Coastguard Worker           dmxTable[pMetadata->surroundMixLevel],
643*e5436536SAndroid Build Coastguard Worker           dmxTable[pMetadata->etsiAncData.extAncData.ext_dmix_a_idx],
644*e5436536SAndroid Build Coastguard Worker           dmxTable[pMetadata->etsiAncData.extAncData.ext_dmix_b_idx],
645*e5436536SAndroid Build Coastguard Worker           pMetadata->etsiAncData.extAncData.ext_lfe_downmix_status
646*e5436536SAndroid Build Coastguard Worker               ? dmxLfeTable[pMetadata->etsiAncData.extAncData.ext_dmix_lfe_idx]
647*e5436536SAndroid Build Coastguard Worker               : (FIXP_DBL)0,
648*e5436536SAndroid Build Coastguard Worker           dmxGain5, dmxGain2, &dynrng, &compr) != 0) {
649*e5436536SAndroid Build Coastguard Worker     err = METADATA_ENCODE_ERROR;
650*e5436536SAndroid Build Coastguard Worker     goto bail;
651*e5436536SAndroid Build Coastguard Worker   }
652*e5436536SAndroid Build Coastguard Worker 
653*e5436536SAndroid Build Coastguard Worker   /* Write DRC values */
654*e5436536SAndroid Build Coastguard Worker   pMetadata->mpegDrc.drc_band_incr = 0;
655*e5436536SAndroid Build Coastguard Worker   encodeDynrng(dynrng, pMetadata->mpegDrc.dyn_rng_ctl,
656*e5436536SAndroid Build Coastguard Worker                pMetadata->mpegDrc.dyn_rng_sgn);
657*e5436536SAndroid Build Coastguard Worker   pMetadata->etsiAncData.compression_value = encodeCompr(compr);
658*e5436536SAndroid Build Coastguard Worker 
659*e5436536SAndroid Build Coastguard Worker bail:
660*e5436536SAndroid Build Coastguard Worker   return err;
661*e5436536SAndroid Build Coastguard Worker }
662*e5436536SAndroid Build Coastguard Worker 
FDK_MetadataEnc_Process(HANDLE_FDK_METADATA_ENCODER hMetaDataEnc,INT_PCM * const pAudioSamples,const UINT audioSamplesBufSize,const INT nAudioSamples,const AACENC_MetaData * const pMetadata,AACENC_EXT_PAYLOAD ** ppMetaDataExtPayload,UINT * nMetaDataExtensions,INT * matrix_mixdown_idx)663*e5436536SAndroid Build Coastguard Worker FDK_METADATA_ERROR FDK_MetadataEnc_Process(
664*e5436536SAndroid Build Coastguard Worker     HANDLE_FDK_METADATA_ENCODER hMetaDataEnc, INT_PCM* const pAudioSamples,
665*e5436536SAndroid Build Coastguard Worker     const UINT audioSamplesBufSize, const INT nAudioSamples,
666*e5436536SAndroid Build Coastguard Worker     const AACENC_MetaData* const pMetadata,
667*e5436536SAndroid Build Coastguard Worker     AACENC_EXT_PAYLOAD** ppMetaDataExtPayload, UINT* nMetaDataExtensions,
668*e5436536SAndroid Build Coastguard Worker     INT* matrix_mixdown_idx) {
669*e5436536SAndroid Build Coastguard Worker   FDK_METADATA_ERROR err = METADATA_OK;
670*e5436536SAndroid Build Coastguard Worker   int metaDataDelayWriteIdx, metaDataDelayReadIdx, metadataMode;
671*e5436536SAndroid Build Coastguard Worker 
672*e5436536SAndroid Build Coastguard Worker   /* Where to write new meta data info */
673*e5436536SAndroid Build Coastguard Worker   metaDataDelayWriteIdx = hMetaDataEnc->metaDataDelayIdx;
674*e5436536SAndroid Build Coastguard Worker 
675*e5436536SAndroid Build Coastguard Worker   /* How to write the data */
676*e5436536SAndroid Build Coastguard Worker   metadataMode = hMetaDataEnc->metadataMode;
677*e5436536SAndroid Build Coastguard Worker 
678*e5436536SAndroid Build Coastguard Worker   /* Compensate meta data delay. */
679*e5436536SAndroid Build Coastguard Worker   hMetaDataEnc->metaDataDelayIdx++;
680*e5436536SAndroid Build Coastguard Worker   if (hMetaDataEnc->metaDataDelayIdx > hMetaDataEnc->nMetaDataDelay)
681*e5436536SAndroid Build Coastguard Worker     hMetaDataEnc->metaDataDelayIdx = 0;
682*e5436536SAndroid Build Coastguard Worker 
683*e5436536SAndroid Build Coastguard Worker   /* Where to read pending meta data info from. */
684*e5436536SAndroid Build Coastguard Worker   metaDataDelayReadIdx = hMetaDataEnc->metaDataDelayIdx;
685*e5436536SAndroid Build Coastguard Worker 
686*e5436536SAndroid Build Coastguard Worker   /* Submit new data if available. */
687*e5436536SAndroid Build Coastguard Worker   if (pMetadata != NULL) {
688*e5436536SAndroid Build Coastguard Worker     FDKmemcpy(&hMetaDataEnc->submittedMetaData, pMetadata,
689*e5436536SAndroid Build Coastguard Worker               sizeof(AACENC_MetaData));
690*e5436536SAndroid Build Coastguard Worker   }
691*e5436536SAndroid Build Coastguard Worker 
692*e5436536SAndroid Build Coastguard Worker   /* Write one additional frame with default configuration of meta data. Ensure
693*e5436536SAndroid Build Coastguard Worker    * defined behaviour on decoder side. */
694*e5436536SAndroid Build Coastguard Worker   if ((hMetaDataEnc->finalizeMetaData != 0) &&
695*e5436536SAndroid Build Coastguard Worker       (hMetaDataEnc->metadataMode == 0)) {
696*e5436536SAndroid Build Coastguard Worker     FDKmemcpy(&hMetaDataEnc->submittedMetaData, &defaultMetaDataSetup,
697*e5436536SAndroid Build Coastguard Worker               sizeof(AACENC_MetaData));
698*e5436536SAndroid Build Coastguard Worker     metadataMode = hMetaDataEnc->finalizeMetaData;
699*e5436536SAndroid Build Coastguard Worker     hMetaDataEnc->finalizeMetaData = 0;
700*e5436536SAndroid Build Coastguard Worker   }
701*e5436536SAndroid Build Coastguard Worker 
702*e5436536SAndroid Build Coastguard Worker   /* Get last submitted data. */
703*e5436536SAndroid Build Coastguard Worker   if ((err = LoadSubmittedMetadata(
704*e5436536SAndroid Build Coastguard Worker            &hMetaDataEnc->submittedMetaData, hMetaDataEnc->nChannels,
705*e5436536SAndroid Build Coastguard Worker            metadataMode,
706*e5436536SAndroid Build Coastguard Worker            &hMetaDataEnc->metaDataBuffer[metaDataDelayWriteIdx])) !=
707*e5436536SAndroid Build Coastguard Worker       METADATA_OK) {
708*e5436536SAndroid Build Coastguard Worker     goto bail;
709*e5436536SAndroid Build Coastguard Worker   }
710*e5436536SAndroid Build Coastguard Worker 
711*e5436536SAndroid Build Coastguard Worker   /* Calculate compressor if necessary and updata meta data info */
712*e5436536SAndroid Build Coastguard Worker   if ((hMetaDataEnc->metaDataBuffer[metaDataDelayWriteIdx].metadataMode == 1) ||
713*e5436536SAndroid Build Coastguard Worker       (hMetaDataEnc->metaDataBuffer[metaDataDelayWriteIdx].metadataMode == 2)) {
714*e5436536SAndroid Build Coastguard Worker     if ((err = ProcessCompressor(
715*e5436536SAndroid Build Coastguard Worker              &hMetaDataEnc->metaDataBuffer[metaDataDelayWriteIdx],
716*e5436536SAndroid Build Coastguard Worker              hMetaDataEnc->hDrcComp, pAudioSamples, audioSamplesBufSize,
717*e5436536SAndroid Build Coastguard Worker              nAudioSamples)) != METADATA_OK) {
718*e5436536SAndroid Build Coastguard Worker       /* Get last submitted data again. */
719*e5436536SAndroid Build Coastguard Worker       LoadSubmittedMetadata(
720*e5436536SAndroid Build Coastguard Worker           &hMetaDataEnc->submittedMetaData, hMetaDataEnc->nChannels,
721*e5436536SAndroid Build Coastguard Worker           metadataMode, &hMetaDataEnc->metaDataBuffer[metaDataDelayWriteIdx]);
722*e5436536SAndroid Build Coastguard Worker     }
723*e5436536SAndroid Build Coastguard Worker   }
724*e5436536SAndroid Build Coastguard Worker 
725*e5436536SAndroid Build Coastguard Worker   /* Fill up delay line with initial meta data info.*/
726*e5436536SAndroid Build Coastguard Worker   if ((hMetaDataEnc->initializeMetaData != 0) &&
727*e5436536SAndroid Build Coastguard Worker       (hMetaDataEnc->metadataMode != 0)) {
728*e5436536SAndroid Build Coastguard Worker     int i;
729*e5436536SAndroid Build Coastguard Worker     for (i = 0;
730*e5436536SAndroid Build Coastguard Worker          i < (int)(sizeof(hMetaDataEnc->metaDataBuffer) / sizeof(AAC_METADATA));
731*e5436536SAndroid Build Coastguard Worker          i++) {
732*e5436536SAndroid Build Coastguard Worker       if (i != metaDataDelayWriteIdx) {
733*e5436536SAndroid Build Coastguard Worker         FDKmemcpy(&hMetaDataEnc->metaDataBuffer[i],
734*e5436536SAndroid Build Coastguard Worker                   &hMetaDataEnc->metaDataBuffer[metaDataDelayWriteIdx],
735*e5436536SAndroid Build Coastguard Worker                   sizeof(hMetaDataEnc->metaDataBuffer[metaDataDelayWriteIdx]));
736*e5436536SAndroid Build Coastguard Worker       }
737*e5436536SAndroid Build Coastguard Worker     }
738*e5436536SAndroid Build Coastguard Worker     hMetaDataEnc->initializeMetaData = 0;
739*e5436536SAndroid Build Coastguard Worker   }
740*e5436536SAndroid Build Coastguard Worker 
741*e5436536SAndroid Build Coastguard Worker   /* Convert Meta Data side info to bitstream data. */
742*e5436536SAndroid Build Coastguard Worker   FDK_ASSERT(metaDataDelayReadIdx < MAX_DELAY_FRAMES);
743*e5436536SAndroid Build Coastguard Worker   if ((err = WriteMetadataPayload(
744*e5436536SAndroid Build Coastguard Worker            hMetaDataEnc,
745*e5436536SAndroid Build Coastguard Worker            &hMetaDataEnc->metaDataBuffer[metaDataDelayReadIdx])) !=
746*e5436536SAndroid Build Coastguard Worker       METADATA_OK) {
747*e5436536SAndroid Build Coastguard Worker     goto bail;
748*e5436536SAndroid Build Coastguard Worker   }
749*e5436536SAndroid Build Coastguard Worker 
750*e5436536SAndroid Build Coastguard Worker   /* Assign meta data to output */
751*e5436536SAndroid Build Coastguard Worker   *ppMetaDataExtPayload = hMetaDataEnc->exPayload;
752*e5436536SAndroid Build Coastguard Worker   *nMetaDataExtensions = hMetaDataEnc->nExtensions;
753*e5436536SAndroid Build Coastguard Worker   *matrix_mixdown_idx = hMetaDataEnc->matrix_mixdown_idx;
754*e5436536SAndroid Build Coastguard Worker 
755*e5436536SAndroid Build Coastguard Worker bail:
756*e5436536SAndroid Build Coastguard Worker   /* Compensate audio delay, reset err status. */
757*e5436536SAndroid Build Coastguard Worker   err = CompensateAudioDelay(hMetaDataEnc, pAudioSamples, audioSamplesBufSize,
758*e5436536SAndroid Build Coastguard Worker                              nAudioSamples / hMetaDataEnc->nChannels);
759*e5436536SAndroid Build Coastguard Worker 
760*e5436536SAndroid Build Coastguard Worker   return err;
761*e5436536SAndroid Build Coastguard Worker }
762*e5436536SAndroid Build Coastguard Worker 
CompensateAudioDelay(HANDLE_FDK_METADATA_ENCODER hMetaDataEnc,INT_PCM * const pAudioSamples,const UINT audioSamplesBufSize,const INT nAudioSamples)763*e5436536SAndroid Build Coastguard Worker static FDK_METADATA_ERROR CompensateAudioDelay(
764*e5436536SAndroid Build Coastguard Worker     HANDLE_FDK_METADATA_ENCODER hMetaDataEnc, INT_PCM* const pAudioSamples,
765*e5436536SAndroid Build Coastguard Worker     const UINT audioSamplesBufSize, const INT nAudioSamples) {
766*e5436536SAndroid Build Coastguard Worker   FDK_METADATA_ERROR err = METADATA_OK;
767*e5436536SAndroid Build Coastguard Worker 
768*e5436536SAndroid Build Coastguard Worker   if (hMetaDataEnc->nAudioDataDelay) {
769*e5436536SAndroid Build Coastguard Worker     C_ALLOC_SCRATCH_START(scratch_audioDelayBuffer, INT_PCM, 1024);
770*e5436536SAndroid Build Coastguard Worker 
771*e5436536SAndroid Build Coastguard Worker     for (int c = 0; c < hMetaDataEnc->nChannels; c++) {
772*e5436536SAndroid Build Coastguard Worker       int M = 1024;
773*e5436536SAndroid Build Coastguard Worker       INT_PCM* pAudioSamples2 = pAudioSamples + c * audioSamplesBufSize;
774*e5436536SAndroid Build Coastguard Worker       int delayIdx = hMetaDataEnc->nAudioDataDelay;
775*e5436536SAndroid Build Coastguard Worker 
776*e5436536SAndroid Build Coastguard Worker       do {
777*e5436536SAndroid Build Coastguard Worker         M = fMin(M, delayIdx);
778*e5436536SAndroid Build Coastguard Worker         delayIdx -= M;
779*e5436536SAndroid Build Coastguard Worker 
780*e5436536SAndroid Build Coastguard Worker         FDKmemcpy(&scratch_audioDelayBuffer[0],
781*e5436536SAndroid Build Coastguard Worker                   &pAudioSamples2[(nAudioSamples - M)], sizeof(INT_PCM) * M);
782*e5436536SAndroid Build Coastguard Worker         FDKmemmove(&pAudioSamples2[M], &pAudioSamples2[0],
783*e5436536SAndroid Build Coastguard Worker                    sizeof(INT_PCM) * (nAudioSamples - M));
784*e5436536SAndroid Build Coastguard Worker         FDKmemcpy(
785*e5436536SAndroid Build Coastguard Worker             &pAudioSamples2[0],
786*e5436536SAndroid Build Coastguard Worker             &hMetaDataEnc->pAudioDelayBuffer[delayIdx +
787*e5436536SAndroid Build Coastguard Worker                                              c * hMetaDataEnc->nAudioDataDelay],
788*e5436536SAndroid Build Coastguard Worker             sizeof(INT_PCM) * M);
789*e5436536SAndroid Build Coastguard Worker         FDKmemcpy(
790*e5436536SAndroid Build Coastguard Worker             &hMetaDataEnc->pAudioDelayBuffer[delayIdx +
791*e5436536SAndroid Build Coastguard Worker                                              c * hMetaDataEnc->nAudioDataDelay],
792*e5436536SAndroid Build Coastguard Worker             &scratch_audioDelayBuffer[0], sizeof(INT_PCM) * M);
793*e5436536SAndroid Build Coastguard Worker 
794*e5436536SAndroid Build Coastguard Worker       } while (delayIdx > 0);
795*e5436536SAndroid Build Coastguard Worker     }
796*e5436536SAndroid Build Coastguard Worker 
797*e5436536SAndroid Build Coastguard Worker     C_ALLOC_SCRATCH_END(scratch_audioDelayBuffer, INT_PCM, 1024);
798*e5436536SAndroid Build Coastguard Worker   }
799*e5436536SAndroid Build Coastguard Worker 
800*e5436536SAndroid Build Coastguard Worker   return err;
801*e5436536SAndroid Build Coastguard Worker }
802*e5436536SAndroid Build Coastguard Worker 
803*e5436536SAndroid Build Coastguard Worker /*-----------------------------------------------------------------------------
804*e5436536SAndroid Build Coastguard Worker 
805*e5436536SAndroid Build Coastguard Worker   functionname: WriteMetadataPayload
806*e5436536SAndroid Build Coastguard Worker   description:  fills anc data and extension payload
807*e5436536SAndroid Build Coastguard Worker   returns:      Error status
808*e5436536SAndroid Build Coastguard Worker 
809*e5436536SAndroid Build Coastguard Worker  ------------------------------------------------------------------------------*/
WriteMetadataPayload(const HANDLE_FDK_METADATA_ENCODER hMetaData,const AAC_METADATA * const pMetadata)810*e5436536SAndroid Build Coastguard Worker static FDK_METADATA_ERROR WriteMetadataPayload(
811*e5436536SAndroid Build Coastguard Worker     const HANDLE_FDK_METADATA_ENCODER hMetaData,
812*e5436536SAndroid Build Coastguard Worker     const AAC_METADATA* const pMetadata) {
813*e5436536SAndroid Build Coastguard Worker   FDK_METADATA_ERROR err = METADATA_OK;
814*e5436536SAndroid Build Coastguard Worker 
815*e5436536SAndroid Build Coastguard Worker   if ((hMetaData == NULL) || (pMetadata == NULL)) {
816*e5436536SAndroid Build Coastguard Worker     err = METADATA_INVALID_HANDLE;
817*e5436536SAndroid Build Coastguard Worker     goto bail;
818*e5436536SAndroid Build Coastguard Worker   }
819*e5436536SAndroid Build Coastguard Worker 
820*e5436536SAndroid Build Coastguard Worker   hMetaData->nExtensions = 0;
821*e5436536SAndroid Build Coastguard Worker   hMetaData->matrix_mixdown_idx = -1;
822*e5436536SAndroid Build Coastguard Worker 
823*e5436536SAndroid Build Coastguard Worker   if (pMetadata->metadataMode != 0) {
824*e5436536SAndroid Build Coastguard Worker     /* AAC-DRC */
825*e5436536SAndroid Build Coastguard Worker     if ((pMetadata->metadataMode == 1) || (pMetadata->metadataMode == 2)) {
826*e5436536SAndroid Build Coastguard Worker       hMetaData->exPayload[hMetaData->nExtensions].pData =
827*e5436536SAndroid Build Coastguard Worker           hMetaData->drcInfoPayload;
828*e5436536SAndroid Build Coastguard Worker       hMetaData->exPayload[hMetaData->nExtensions].dataType = EXT_DYNAMIC_RANGE;
829*e5436536SAndroid Build Coastguard Worker       hMetaData->exPayload[hMetaData->nExtensions].associatedChElement = -1;
830*e5436536SAndroid Build Coastguard Worker 
831*e5436536SAndroid Build Coastguard Worker       hMetaData->exPayload[hMetaData->nExtensions].dataSize =
832*e5436536SAndroid Build Coastguard Worker           WriteDynamicRangeInfoPayload(
833*e5436536SAndroid Build Coastguard Worker               pMetadata, hMetaData->exPayload[hMetaData->nExtensions].pData);
834*e5436536SAndroid Build Coastguard Worker 
835*e5436536SAndroid Build Coastguard Worker       hMetaData->nExtensions++;
836*e5436536SAndroid Build Coastguard Worker     } /* pMetadata->metadataMode==1 || pMetadata->metadataMode==2 */
837*e5436536SAndroid Build Coastguard Worker 
838*e5436536SAndroid Build Coastguard Worker     /* Matrix Mixdown Coefficient in PCE */
839*e5436536SAndroid Build Coastguard Worker     if (pMetadata->WritePCEMixDwnIdx) {
840*e5436536SAndroid Build Coastguard Worker       hMetaData->matrix_mixdown_idx =
841*e5436536SAndroid Build Coastguard Worker           surmix2matrix_mixdown_idx[pMetadata->surroundMixLevel];
842*e5436536SAndroid Build Coastguard Worker     }
843*e5436536SAndroid Build Coastguard Worker 
844*e5436536SAndroid Build Coastguard Worker     /* ETSI TS 101 154 (DVB) - MPEG4 ancillary_data() */
845*e5436536SAndroid Build Coastguard Worker     if ((pMetadata->metadataMode == 2) ||
846*e5436536SAndroid Build Coastguard Worker         (pMetadata->metadataMode == 3)) /* MP4_METADATA_MPEG_ETSI */
847*e5436536SAndroid Build Coastguard Worker     {
848*e5436536SAndroid Build Coastguard Worker       hMetaData->exPayload[hMetaData->nExtensions].pData =
849*e5436536SAndroid Build Coastguard Worker           hMetaData->drcDsePayload;
850*e5436536SAndroid Build Coastguard Worker       hMetaData->exPayload[hMetaData->nExtensions].dataType = EXT_DATA_ELEMENT;
851*e5436536SAndroid Build Coastguard Worker       hMetaData->exPayload[hMetaData->nExtensions].associatedChElement = -1;
852*e5436536SAndroid Build Coastguard Worker 
853*e5436536SAndroid Build Coastguard Worker       hMetaData->exPayload[hMetaData->nExtensions].dataSize =
854*e5436536SAndroid Build Coastguard Worker           WriteEtsiAncillaryDataPayload(
855*e5436536SAndroid Build Coastguard Worker               pMetadata, hMetaData->exPayload[hMetaData->nExtensions].pData);
856*e5436536SAndroid Build Coastguard Worker 
857*e5436536SAndroid Build Coastguard Worker       hMetaData->nExtensions++;
858*e5436536SAndroid Build Coastguard Worker     } /* metadataMode==2 || metadataMode==3 */
859*e5436536SAndroid Build Coastguard Worker 
860*e5436536SAndroid Build Coastguard Worker   } /* metadataMode != 0 */
861*e5436536SAndroid Build Coastguard Worker 
862*e5436536SAndroid Build Coastguard Worker bail:
863*e5436536SAndroid Build Coastguard Worker   return err;
864*e5436536SAndroid Build Coastguard Worker }
865*e5436536SAndroid Build Coastguard Worker 
WriteDynamicRangeInfoPayload(const AAC_METADATA * const pMetadata,UCHAR * const pExtensionPayload)866*e5436536SAndroid Build Coastguard Worker static INT WriteDynamicRangeInfoPayload(const AAC_METADATA* const pMetadata,
867*e5436536SAndroid Build Coastguard Worker                                         UCHAR* const pExtensionPayload) {
868*e5436536SAndroid Build Coastguard Worker   const INT pce_tag_present = 0; /* yet fixed setting! */
869*e5436536SAndroid Build Coastguard Worker   const INT prog_ref_lev_res_bits = 0;
870*e5436536SAndroid Build Coastguard Worker   INT i, drc_num_bands = 1;
871*e5436536SAndroid Build Coastguard Worker 
872*e5436536SAndroid Build Coastguard Worker   FDK_BITSTREAM bsWriter;
873*e5436536SAndroid Build Coastguard Worker   FDKinitBitStream(&bsWriter, pExtensionPayload, 16, 0, BS_WRITER);
874*e5436536SAndroid Build Coastguard Worker 
875*e5436536SAndroid Build Coastguard Worker   /* dynamic_range_info() */
876*e5436536SAndroid Build Coastguard Worker   FDKwriteBits(&bsWriter, pce_tag_present, 1); /* pce_tag_present */
877*e5436536SAndroid Build Coastguard Worker   if (pce_tag_present) {
878*e5436536SAndroid Build Coastguard Worker     FDKwriteBits(&bsWriter, 0x0, 4); /* pce_instance_tag */
879*e5436536SAndroid Build Coastguard Worker     FDKwriteBits(&bsWriter, 0x0, 4); /* drc_tag_reserved_bits */
880*e5436536SAndroid Build Coastguard Worker   }
881*e5436536SAndroid Build Coastguard Worker 
882*e5436536SAndroid Build Coastguard Worker   /* Exclude channels */
883*e5436536SAndroid Build Coastguard Worker   FDKwriteBits(&bsWriter, (pMetadata->mpegDrc.excluded_chns_present) ? 1 : 0,
884*e5436536SAndroid Build Coastguard Worker                1); /* excluded_chns_present*/
885*e5436536SAndroid Build Coastguard Worker 
886*e5436536SAndroid Build Coastguard Worker   /* Multiband DRC */
887*e5436536SAndroid Build Coastguard Worker   FDKwriteBits(&bsWriter, (pMetadata->mpegDrc.drc_bands_present) ? 1 : 0,
888*e5436536SAndroid Build Coastguard Worker                1); /* drc_bands_present */
889*e5436536SAndroid Build Coastguard Worker   if (pMetadata->mpegDrc.drc_bands_present) {
890*e5436536SAndroid Build Coastguard Worker     FDKwriteBits(&bsWriter, pMetadata->mpegDrc.drc_band_incr,
891*e5436536SAndroid Build Coastguard Worker                  4); /* drc_band_incr */
892*e5436536SAndroid Build Coastguard Worker     FDKwriteBits(&bsWriter, pMetadata->mpegDrc.drc_interpolation_scheme,
893*e5436536SAndroid Build Coastguard Worker                  4); /* drc_interpolation_scheme */
894*e5436536SAndroid Build Coastguard Worker     drc_num_bands += pMetadata->mpegDrc.drc_band_incr;
895*e5436536SAndroid Build Coastguard Worker     for (i = 0; i < drc_num_bands; i++) {
896*e5436536SAndroid Build Coastguard Worker       FDKwriteBits(&bsWriter, pMetadata->mpegDrc.drc_band_top[i],
897*e5436536SAndroid Build Coastguard Worker                    8); /* drc_band_top */
898*e5436536SAndroid Build Coastguard Worker     }
899*e5436536SAndroid Build Coastguard Worker   }
900*e5436536SAndroid Build Coastguard Worker 
901*e5436536SAndroid Build Coastguard Worker   /* Program Reference Level */
902*e5436536SAndroid Build Coastguard Worker   FDKwriteBits(&bsWriter, pMetadata->mpegDrc.prog_ref_level_present,
903*e5436536SAndroid Build Coastguard Worker                1); /* prog_ref_level_present */
904*e5436536SAndroid Build Coastguard Worker   if (pMetadata->mpegDrc.prog_ref_level_present) {
905*e5436536SAndroid Build Coastguard Worker     FDKwriteBits(&bsWriter, pMetadata->mpegDrc.prog_ref_level,
906*e5436536SAndroid Build Coastguard Worker                  7); /* prog_ref_level */
907*e5436536SAndroid Build Coastguard Worker     FDKwriteBits(&bsWriter, prog_ref_lev_res_bits,
908*e5436536SAndroid Build Coastguard Worker                  1); /* prog_ref_level_reserved_bits */
909*e5436536SAndroid Build Coastguard Worker   }
910*e5436536SAndroid Build Coastguard Worker 
911*e5436536SAndroid Build Coastguard Worker   /* DRC Values */
912*e5436536SAndroid Build Coastguard Worker   for (i = 0; i < drc_num_bands; i++) {
913*e5436536SAndroid Build Coastguard Worker     FDKwriteBits(&bsWriter, (pMetadata->mpegDrc.dyn_rng_sgn[i]) ? 1 : 0,
914*e5436536SAndroid Build Coastguard Worker                  1); /* dyn_rng_sgn[ */
915*e5436536SAndroid Build Coastguard Worker     FDKwriteBits(&bsWriter, pMetadata->mpegDrc.dyn_rng_ctl[i],
916*e5436536SAndroid Build Coastguard Worker                  7); /* dyn_rng_ctl */
917*e5436536SAndroid Build Coastguard Worker   }
918*e5436536SAndroid Build Coastguard Worker 
919*e5436536SAndroid Build Coastguard Worker   /* return number of valid bits in extension payload. */
920*e5436536SAndroid Build Coastguard Worker   return FDKgetValidBits(&bsWriter);
921*e5436536SAndroid Build Coastguard Worker }
922*e5436536SAndroid Build Coastguard Worker 
WriteEtsiAncillaryDataPayload(const AAC_METADATA * const pMetadata,UCHAR * const pExtensionPayload)923*e5436536SAndroid Build Coastguard Worker static INT WriteEtsiAncillaryDataPayload(const AAC_METADATA* const pMetadata,
924*e5436536SAndroid Build Coastguard Worker                                          UCHAR* const pExtensionPayload) {
925*e5436536SAndroid Build Coastguard Worker   FDK_BITSTREAM bsWriter;
926*e5436536SAndroid Build Coastguard Worker   FDKinitBitStream(&bsWriter, pExtensionPayload, 16, 0, BS_WRITER);
927*e5436536SAndroid Build Coastguard Worker 
928*e5436536SAndroid Build Coastguard Worker   /* ancillary_data_sync */
929*e5436536SAndroid Build Coastguard Worker   FDKwriteBits(&bsWriter, 0xBC, 8);
930*e5436536SAndroid Build Coastguard Worker 
931*e5436536SAndroid Build Coastguard Worker   /* bs_info */
932*e5436536SAndroid Build Coastguard Worker   FDKwriteBits(&bsWriter, 0x3, 2); /* mpeg_audio_type */
933*e5436536SAndroid Build Coastguard Worker   FDKwriteBits(&bsWriter, pMetadata->dolbySurroundMode,
934*e5436536SAndroid Build Coastguard Worker                2); /* dolby_surround_mode */
935*e5436536SAndroid Build Coastguard Worker   FDKwriteBits(&bsWriter, pMetadata->drcPresentationMode,
936*e5436536SAndroid Build Coastguard Worker                2);                 /* DRC presentation mode */
937*e5436536SAndroid Build Coastguard Worker   FDKwriteBits(&bsWriter, 0x0, 1); /* stereo_downmix_mode */
938*e5436536SAndroid Build Coastguard Worker   FDKwriteBits(&bsWriter, 0x0, 1); /* reserved */
939*e5436536SAndroid Build Coastguard Worker 
940*e5436536SAndroid Build Coastguard Worker   /* ancillary_data_status */
941*e5436536SAndroid Build Coastguard Worker   FDKwriteBits(&bsWriter, 0, 3); /* 3 bit Reserved, set to "0" */
942*e5436536SAndroid Build Coastguard Worker   FDKwriteBits(&bsWriter, (pMetadata->DmxLvl_On) ? 1 : 0,
943*e5436536SAndroid Build Coastguard Worker                1); /* downmixing_levels_MPEG4_status */
944*e5436536SAndroid Build Coastguard Worker   FDKwriteBits(&bsWriter, pMetadata->etsiAncData.extAncDataStatus,
945*e5436536SAndroid Build Coastguard Worker                1); /* ext_anc_data_status */
946*e5436536SAndroid Build Coastguard Worker   FDKwriteBits(&bsWriter, (pMetadata->etsiAncData.compression_on) ? 1 : 0,
947*e5436536SAndroid Build Coastguard Worker                1); /* audio_coding_mode_and_compression status */
948*e5436536SAndroid Build Coastguard Worker   FDKwriteBits(&bsWriter,
949*e5436536SAndroid Build Coastguard Worker                (pMetadata->etsiAncData.timecode_coarse_status) ? 1 : 0,
950*e5436536SAndroid Build Coastguard Worker                1); /* coarse_grain_timecode_status */
951*e5436536SAndroid Build Coastguard Worker   FDKwriteBits(&bsWriter, (pMetadata->etsiAncData.timecode_fine_status) ? 1 : 0,
952*e5436536SAndroid Build Coastguard Worker                1); /* fine_grain_timecode_status */
953*e5436536SAndroid Build Coastguard Worker 
954*e5436536SAndroid Build Coastguard Worker   /* downmixing_levels_MPEG4_status */
955*e5436536SAndroid Build Coastguard Worker   if (pMetadata->DmxLvl_On) {
956*e5436536SAndroid Build Coastguard Worker     FDKwriteBits(
957*e5436536SAndroid Build Coastguard Worker         &bsWriter,
958*e5436536SAndroid Build Coastguard Worker         encodeDmxLvls(pMetadata->centerMixLevel, pMetadata->surroundMixLevel),
959*e5436536SAndroid Build Coastguard Worker         8);
960*e5436536SAndroid Build Coastguard Worker   }
961*e5436536SAndroid Build Coastguard Worker 
962*e5436536SAndroid Build Coastguard Worker   /* audio_coding_mode_and_compression_status */
963*e5436536SAndroid Build Coastguard Worker   if (pMetadata->etsiAncData.compression_on) {
964*e5436536SAndroid Build Coastguard Worker     FDKwriteBits(&bsWriter, 0x01, 8); /* audio coding mode */
965*e5436536SAndroid Build Coastguard Worker     FDKwriteBits(&bsWriter, pMetadata->etsiAncData.compression_value,
966*e5436536SAndroid Build Coastguard Worker                  8); /* compression value */
967*e5436536SAndroid Build Coastguard Worker   }
968*e5436536SAndroid Build Coastguard Worker 
969*e5436536SAndroid Build Coastguard Worker   /* grain-timecode coarse/fine */
970*e5436536SAndroid Build Coastguard Worker   if (pMetadata->etsiAncData.timecode_coarse_status) {
971*e5436536SAndroid Build Coastguard Worker     FDKwriteBits(&bsWriter, 0x0, 16); /* not yet supported */
972*e5436536SAndroid Build Coastguard Worker   }
973*e5436536SAndroid Build Coastguard Worker 
974*e5436536SAndroid Build Coastguard Worker   if (pMetadata->etsiAncData.timecode_fine_status) {
975*e5436536SAndroid Build Coastguard Worker     FDKwriteBits(&bsWriter, 0x0, 16); /* not yet supported */
976*e5436536SAndroid Build Coastguard Worker   }
977*e5436536SAndroid Build Coastguard Worker 
978*e5436536SAndroid Build Coastguard Worker   /* extended ancillary data structure */
979*e5436536SAndroid Build Coastguard Worker   if (pMetadata->etsiAncData.extAncDataStatus) {
980*e5436536SAndroid Build Coastguard Worker     /* ext_ancillary_data_status */
981*e5436536SAndroid Build Coastguard Worker     FDKwriteBits(&bsWriter, 0, 1); /* Reserved, set to "0" */
982*e5436536SAndroid Build Coastguard Worker     FDKwriteBits(&bsWriter,
983*e5436536SAndroid Build Coastguard Worker                  pMetadata->etsiAncData.extAncData.ext_downmix_lvl_status,
984*e5436536SAndroid Build Coastguard Worker                  1); /* ext_downmixing_levels_status */
985*e5436536SAndroid Build Coastguard Worker     FDKwriteBits(&bsWriter,
986*e5436536SAndroid Build Coastguard Worker                  pMetadata->etsiAncData.extAncData.ext_downmix_gain_status,
987*e5436536SAndroid Build Coastguard Worker                  1); /* ext_downmixing_global_gains_status */
988*e5436536SAndroid Build Coastguard Worker     FDKwriteBits(&bsWriter,
989*e5436536SAndroid Build Coastguard Worker                  pMetadata->etsiAncData.extAncData.ext_lfe_downmix_status,
990*e5436536SAndroid Build Coastguard Worker                  1);               /* ext_downmixing_lfe_level_status" */
991*e5436536SAndroid Build Coastguard Worker     FDKwriteBits(&bsWriter, 0, 4); /* Reserved, set to "0" */
992*e5436536SAndroid Build Coastguard Worker 
993*e5436536SAndroid Build Coastguard Worker     /* ext_downmixing_levels */
994*e5436536SAndroid Build Coastguard Worker     if (pMetadata->etsiAncData.extAncData.ext_downmix_lvl_status) {
995*e5436536SAndroid Build Coastguard Worker       FDKwriteBits(&bsWriter, pMetadata->etsiAncData.extAncData.ext_dmix_a_idx,
996*e5436536SAndroid Build Coastguard Worker                    3); /* dmix_a_idx */
997*e5436536SAndroid Build Coastguard Worker       FDKwriteBits(&bsWriter, pMetadata->etsiAncData.extAncData.ext_dmix_b_idx,
998*e5436536SAndroid Build Coastguard Worker                    3);               /* dmix_b_idx */
999*e5436536SAndroid Build Coastguard Worker       FDKwriteBits(&bsWriter, 0, 2); /* Reserved, set to "0" */
1000*e5436536SAndroid Build Coastguard Worker     }
1001*e5436536SAndroid Build Coastguard Worker 
1002*e5436536SAndroid Build Coastguard Worker     /* ext_downmixing_gains */
1003*e5436536SAndroid Build Coastguard Worker     if (pMetadata->etsiAncData.extAncData.ext_downmix_gain_status) {
1004*e5436536SAndroid Build Coastguard Worker       FDKwriteBits(&bsWriter, pMetadata->etsiAncData.extAncData.dmx_gain_5_sgn,
1005*e5436536SAndroid Build Coastguard Worker                    1); /* dmx_gain_5_sign */
1006*e5436536SAndroid Build Coastguard Worker       FDKwriteBits(&bsWriter, pMetadata->etsiAncData.extAncData.dmx_gain_5_idx,
1007*e5436536SAndroid Build Coastguard Worker                    6);               /* dmx_gain_5_idx */
1008*e5436536SAndroid Build Coastguard Worker       FDKwriteBits(&bsWriter, 0, 1); /* Reserved, set to "0" */
1009*e5436536SAndroid Build Coastguard Worker       FDKwriteBits(&bsWriter, pMetadata->etsiAncData.extAncData.dmx_gain_2_sgn,
1010*e5436536SAndroid Build Coastguard Worker                    1); /* dmx_gain_2_sign */
1011*e5436536SAndroid Build Coastguard Worker       FDKwriteBits(&bsWriter, pMetadata->etsiAncData.extAncData.dmx_gain_2_idx,
1012*e5436536SAndroid Build Coastguard Worker                    6);               /* dmx_gain_2_idx */
1013*e5436536SAndroid Build Coastguard Worker       FDKwriteBits(&bsWriter, 0, 1); /* Reserved, set to "0" */
1014*e5436536SAndroid Build Coastguard Worker     }
1015*e5436536SAndroid Build Coastguard Worker 
1016*e5436536SAndroid Build Coastguard Worker     if (pMetadata->etsiAncData.extAncData.ext_lfe_downmix_status) {
1017*e5436536SAndroid Build Coastguard Worker       FDKwriteBits(&bsWriter,
1018*e5436536SAndroid Build Coastguard Worker                    pMetadata->etsiAncData.extAncData.ext_dmix_lfe_idx,
1019*e5436536SAndroid Build Coastguard Worker                    4);               /* dmix_lfe_idx */
1020*e5436536SAndroid Build Coastguard Worker       FDKwriteBits(&bsWriter, 0, 4); /* Reserved, set to "0" */
1021*e5436536SAndroid Build Coastguard Worker     }
1022*e5436536SAndroid Build Coastguard Worker   }
1023*e5436536SAndroid Build Coastguard Worker 
1024*e5436536SAndroid Build Coastguard Worker   return FDKgetValidBits(&bsWriter);
1025*e5436536SAndroid Build Coastguard Worker }
1026*e5436536SAndroid Build Coastguard Worker 
LoadSubmittedMetadata(const AACENC_MetaData * const hMetadata,const INT nChannels,const INT metadataMode,AAC_METADATA * const pAacMetaData)1027*e5436536SAndroid Build Coastguard Worker static FDK_METADATA_ERROR LoadSubmittedMetadata(
1028*e5436536SAndroid Build Coastguard Worker     const AACENC_MetaData* const hMetadata, const INT nChannels,
1029*e5436536SAndroid Build Coastguard Worker     const INT metadataMode, AAC_METADATA* const pAacMetaData) {
1030*e5436536SAndroid Build Coastguard Worker   FDK_METADATA_ERROR err = METADATA_OK;
1031*e5436536SAndroid Build Coastguard Worker 
1032*e5436536SAndroid Build Coastguard Worker   if (pAacMetaData == NULL) {
1033*e5436536SAndroid Build Coastguard Worker     err = METADATA_INVALID_HANDLE;
1034*e5436536SAndroid Build Coastguard Worker   } else {
1035*e5436536SAndroid Build Coastguard Worker     /* init struct */
1036*e5436536SAndroid Build Coastguard Worker     FDKmemclear(pAacMetaData, sizeof(AAC_METADATA));
1037*e5436536SAndroid Build Coastguard Worker 
1038*e5436536SAndroid Build Coastguard Worker     if (hMetadata != NULL) {
1039*e5436536SAndroid Build Coastguard Worker       /* convert data */
1040*e5436536SAndroid Build Coastguard Worker       pAacMetaData->mpegDrc.drc_profile = hMetadata->drc_profile;
1041*e5436536SAndroid Build Coastguard Worker       pAacMetaData->etsiAncData.comp_profile = hMetadata->comp_profile;
1042*e5436536SAndroid Build Coastguard Worker       pAacMetaData->mpegDrc.drc_TargetRefLevel = hMetadata->drc_TargetRefLevel;
1043*e5436536SAndroid Build Coastguard Worker       pAacMetaData->etsiAncData.comp_TargetRefLevel =
1044*e5436536SAndroid Build Coastguard Worker           hMetadata->comp_TargetRefLevel;
1045*e5436536SAndroid Build Coastguard Worker       pAacMetaData->mpegDrc.prog_ref_level_present =
1046*e5436536SAndroid Build Coastguard Worker           hMetadata->prog_ref_level_present;
1047*e5436536SAndroid Build Coastguard Worker       pAacMetaData->mpegDrc.prog_ref_level =
1048*e5436536SAndroid Build Coastguard Worker           dialnorm2progreflvl(hMetadata->prog_ref_level);
1049*e5436536SAndroid Build Coastguard Worker 
1050*e5436536SAndroid Build Coastguard Worker       pAacMetaData->centerMixLevel = hMetadata->centerMixLevel;
1051*e5436536SAndroid Build Coastguard Worker       pAacMetaData->surroundMixLevel = hMetadata->surroundMixLevel;
1052*e5436536SAndroid Build Coastguard Worker       pAacMetaData->WritePCEMixDwnIdx = hMetadata->PCE_mixdown_idx_present;
1053*e5436536SAndroid Build Coastguard Worker       pAacMetaData->DmxLvl_On = hMetadata->ETSI_DmxLvl_present;
1054*e5436536SAndroid Build Coastguard Worker 
1055*e5436536SAndroid Build Coastguard Worker       pAacMetaData->etsiAncData.compression_on =
1056*e5436536SAndroid Build Coastguard Worker           (hMetadata->comp_profile == AACENC_METADATA_DRC_NOT_PRESENT ? 0 : 1);
1057*e5436536SAndroid Build Coastguard Worker 
1058*e5436536SAndroid Build Coastguard Worker       if (pAacMetaData->mpegDrc.drc_profile ==
1059*e5436536SAndroid Build Coastguard Worker           AACENC_METADATA_DRC_NOT_PRESENT) {
1060*e5436536SAndroid Build Coastguard Worker         pAacMetaData->mpegDrc.drc_profile =
1061*e5436536SAndroid Build Coastguard Worker             AACENC_METADATA_DRC_NONE; /* MPEG DRC gains are
1062*e5436536SAndroid Build Coastguard Worker                                          always present in BS
1063*e5436536SAndroid Build Coastguard Worker                                          syntax */
1064*e5436536SAndroid Build Coastguard Worker         /* we should give a warning, but ErrorHandler does not support this */
1065*e5436536SAndroid Build Coastguard Worker       }
1066*e5436536SAndroid Build Coastguard Worker 
1067*e5436536SAndroid Build Coastguard Worker       if (nChannels == 2) {
1068*e5436536SAndroid Build Coastguard Worker         pAacMetaData->dolbySurroundMode =
1069*e5436536SAndroid Build Coastguard Worker             hMetadata->dolbySurroundMode; /* dolby_surround_mode */
1070*e5436536SAndroid Build Coastguard Worker       } else {
1071*e5436536SAndroid Build Coastguard Worker         pAacMetaData->dolbySurroundMode = 0;
1072*e5436536SAndroid Build Coastguard Worker       }
1073*e5436536SAndroid Build Coastguard Worker 
1074*e5436536SAndroid Build Coastguard Worker       pAacMetaData->drcPresentationMode = hMetadata->drcPresentationMode;
1075*e5436536SAndroid Build Coastguard Worker       /* override external values if DVB DRC presentation mode is given */
1076*e5436536SAndroid Build Coastguard Worker       if (pAacMetaData->drcPresentationMode == 1) {
1077*e5436536SAndroid Build Coastguard Worker         pAacMetaData->mpegDrc.drc_TargetRefLevel =
1078*e5436536SAndroid Build Coastguard Worker             fMax(-(31 << 16), pAacMetaData->mpegDrc.drc_TargetRefLevel);
1079*e5436536SAndroid Build Coastguard Worker         pAacMetaData->etsiAncData.comp_TargetRefLevel = fMax(
1080*e5436536SAndroid Build Coastguard Worker             -(20 << 16),
1081*e5436536SAndroid Build Coastguard Worker             pAacMetaData->etsiAncData.comp_TargetRefLevel); /* implies -23dB */
1082*e5436536SAndroid Build Coastguard Worker       }
1083*e5436536SAndroid Build Coastguard Worker       if (pAacMetaData->drcPresentationMode == 2) {
1084*e5436536SAndroid Build Coastguard Worker         pAacMetaData->mpegDrc.drc_TargetRefLevel =
1085*e5436536SAndroid Build Coastguard Worker             fMax(-(23 << 16), pAacMetaData->mpegDrc.drc_TargetRefLevel);
1086*e5436536SAndroid Build Coastguard Worker         pAacMetaData->etsiAncData.comp_TargetRefLevel =
1087*e5436536SAndroid Build Coastguard Worker             fMax(-(23 << 16), pAacMetaData->etsiAncData.comp_TargetRefLevel);
1088*e5436536SAndroid Build Coastguard Worker       }
1089*e5436536SAndroid Build Coastguard Worker       if (pAacMetaData->etsiAncData.comp_profile ==
1090*e5436536SAndroid Build Coastguard Worker           AACENC_METADATA_DRC_NOT_PRESENT) {
1091*e5436536SAndroid Build Coastguard Worker         /* DVB defines to revert to Light DRC if heavy is not present */
1092*e5436536SAndroid Build Coastguard Worker         if (pAacMetaData->drcPresentationMode != 0) {
1093*e5436536SAndroid Build Coastguard Worker           /* we exclude the "not indicated" mode as this requires the user to
1094*e5436536SAndroid Build Coastguard Worker            * define desired levels anyway */
1095*e5436536SAndroid Build Coastguard Worker           pAacMetaData->mpegDrc.drc_TargetRefLevel =
1096*e5436536SAndroid Build Coastguard Worker               fMax(pAacMetaData->etsiAncData.comp_TargetRefLevel,
1097*e5436536SAndroid Build Coastguard Worker                    pAacMetaData->mpegDrc.drc_TargetRefLevel);
1098*e5436536SAndroid Build Coastguard Worker         }
1099*e5436536SAndroid Build Coastguard Worker       }
1100*e5436536SAndroid Build Coastguard Worker 
1101*e5436536SAndroid Build Coastguard Worker       pAacMetaData->etsiAncData.timecode_coarse_status =
1102*e5436536SAndroid Build Coastguard Worker           0; /* not yet supported - attention: Update
1103*e5436536SAndroid Build Coastguard Worker                 GetEstMetadataBytesPerFrame() if enable this! */
1104*e5436536SAndroid Build Coastguard Worker       pAacMetaData->etsiAncData.timecode_fine_status =
1105*e5436536SAndroid Build Coastguard Worker           0; /* not yet supported - attention: Update
1106*e5436536SAndroid Build Coastguard Worker                 GetEstMetadataBytesPerFrame() if enable this! */
1107*e5436536SAndroid Build Coastguard Worker 
1108*e5436536SAndroid Build Coastguard Worker       /* extended ancillary data */
1109*e5436536SAndroid Build Coastguard Worker       pAacMetaData->etsiAncData.extAncDataStatus =
1110*e5436536SAndroid Build Coastguard Worker           ((hMetadata->ExtMetaData.extAncDataEnable == 1) ? 1 : 0);
1111*e5436536SAndroid Build Coastguard Worker 
1112*e5436536SAndroid Build Coastguard Worker       if (pAacMetaData->etsiAncData.extAncDataStatus) {
1113*e5436536SAndroid Build Coastguard Worker         pAacMetaData->etsiAncData.extAncData.ext_downmix_lvl_status =
1114*e5436536SAndroid Build Coastguard Worker             (hMetadata->ExtMetaData.extDownmixLevelEnable ? 1 : 0);
1115*e5436536SAndroid Build Coastguard Worker         pAacMetaData->etsiAncData.extAncData.ext_downmix_gain_status =
1116*e5436536SAndroid Build Coastguard Worker             (hMetadata->ExtMetaData.dmxGainEnable ? 1 : 0);
1117*e5436536SAndroid Build Coastguard Worker         pAacMetaData->etsiAncData.extAncData.ext_lfe_downmix_status =
1118*e5436536SAndroid Build Coastguard Worker             (hMetadata->ExtMetaData.lfeDmxEnable ? 1 : 0);
1119*e5436536SAndroid Build Coastguard Worker 
1120*e5436536SAndroid Build Coastguard Worker         pAacMetaData->etsiAncData.extAncData.ext_dmix_a_idx =
1121*e5436536SAndroid Build Coastguard Worker             hMetadata->ExtMetaData.extDownmixLevel_A;
1122*e5436536SAndroid Build Coastguard Worker         pAacMetaData->etsiAncData.extAncData.ext_dmix_b_idx =
1123*e5436536SAndroid Build Coastguard Worker             hMetadata->ExtMetaData.extDownmixLevel_B;
1124*e5436536SAndroid Build Coastguard Worker 
1125*e5436536SAndroid Build Coastguard Worker         if (pAacMetaData->etsiAncData.extAncData.ext_downmix_gain_status) {
1126*e5436536SAndroid Build Coastguard Worker           encodeDynrng(hMetadata->ExtMetaData.dmxGain5,
1127*e5436536SAndroid Build Coastguard Worker                        &(pAacMetaData->etsiAncData.extAncData.dmx_gain_5_idx),
1128*e5436536SAndroid Build Coastguard Worker                        &(pAacMetaData->etsiAncData.extAncData.dmx_gain_5_sgn));
1129*e5436536SAndroid Build Coastguard Worker           encodeDynrng(hMetadata->ExtMetaData.dmxGain2,
1130*e5436536SAndroid Build Coastguard Worker                        &(pAacMetaData->etsiAncData.extAncData.dmx_gain_2_idx),
1131*e5436536SAndroid Build Coastguard Worker                        &(pAacMetaData->etsiAncData.extAncData.dmx_gain_2_sgn));
1132*e5436536SAndroid Build Coastguard Worker         } else {
1133*e5436536SAndroid Build Coastguard Worker           encodeDynrng(1 << 16,
1134*e5436536SAndroid Build Coastguard Worker                        &(pAacMetaData->etsiAncData.extAncData.dmx_gain_5_idx),
1135*e5436536SAndroid Build Coastguard Worker                        &(pAacMetaData->etsiAncData.extAncData.dmx_gain_5_sgn));
1136*e5436536SAndroid Build Coastguard Worker           encodeDynrng(1 << 16,
1137*e5436536SAndroid Build Coastguard Worker                        &(pAacMetaData->etsiAncData.extAncData.dmx_gain_2_idx),
1138*e5436536SAndroid Build Coastguard Worker                        &(pAacMetaData->etsiAncData.extAncData.dmx_gain_2_sgn));
1139*e5436536SAndroid Build Coastguard Worker         }
1140*e5436536SAndroid Build Coastguard Worker 
1141*e5436536SAndroid Build Coastguard Worker         if (pAacMetaData->etsiAncData.extAncData.ext_lfe_downmix_status) {
1142*e5436536SAndroid Build Coastguard Worker           pAacMetaData->etsiAncData.extAncData.ext_dmix_lfe_idx =
1143*e5436536SAndroid Build Coastguard Worker               hMetadata->ExtMetaData.lfeDmxLevel;
1144*e5436536SAndroid Build Coastguard Worker         } else {
1145*e5436536SAndroid Build Coastguard Worker           pAacMetaData->etsiAncData.extAncData.ext_dmix_lfe_idx =
1146*e5436536SAndroid Build Coastguard Worker               15; /* -inf dB */
1147*e5436536SAndroid Build Coastguard Worker         }
1148*e5436536SAndroid Build Coastguard Worker       } else {
1149*e5436536SAndroid Build Coastguard Worker         pAacMetaData->etsiAncData.extAncData.ext_downmix_lvl_status = 0;
1150*e5436536SAndroid Build Coastguard Worker         pAacMetaData->etsiAncData.extAncData.ext_downmix_gain_status = 0;
1151*e5436536SAndroid Build Coastguard Worker         pAacMetaData->etsiAncData.extAncData.ext_lfe_downmix_status = 0;
1152*e5436536SAndroid Build Coastguard Worker 
1153*e5436536SAndroid Build Coastguard Worker         pAacMetaData->etsiAncData.extAncData.ext_dmix_a_idx = 7; /* -inf dB */
1154*e5436536SAndroid Build Coastguard Worker         pAacMetaData->etsiAncData.extAncData.ext_dmix_b_idx = 7; /* -inf dB */
1155*e5436536SAndroid Build Coastguard Worker 
1156*e5436536SAndroid Build Coastguard Worker         encodeDynrng(1 << 16,
1157*e5436536SAndroid Build Coastguard Worker                      &(pAacMetaData->etsiAncData.extAncData.dmx_gain_5_idx),
1158*e5436536SAndroid Build Coastguard Worker                      &(pAacMetaData->etsiAncData.extAncData.dmx_gain_5_sgn));
1159*e5436536SAndroid Build Coastguard Worker         encodeDynrng(1 << 16,
1160*e5436536SAndroid Build Coastguard Worker                      &(pAacMetaData->etsiAncData.extAncData.dmx_gain_2_idx),
1161*e5436536SAndroid Build Coastguard Worker                      &(pAacMetaData->etsiAncData.extAncData.dmx_gain_2_sgn));
1162*e5436536SAndroid Build Coastguard Worker 
1163*e5436536SAndroid Build Coastguard Worker         pAacMetaData->etsiAncData.extAncData.ext_dmix_lfe_idx =
1164*e5436536SAndroid Build Coastguard Worker             15; /* -inf dB */
1165*e5436536SAndroid Build Coastguard Worker       }
1166*e5436536SAndroid Build Coastguard Worker 
1167*e5436536SAndroid Build Coastguard Worker       pAacMetaData->metadataMode = metadataMode;
1168*e5436536SAndroid Build Coastguard Worker     } else {
1169*e5436536SAndroid Build Coastguard Worker       pAacMetaData->metadataMode = 0; /* there is no configuration available */
1170*e5436536SAndroid Build Coastguard Worker     }
1171*e5436536SAndroid Build Coastguard Worker   }
1172*e5436536SAndroid Build Coastguard Worker 
1173*e5436536SAndroid Build Coastguard Worker   return err;
1174*e5436536SAndroid Build Coastguard Worker }
1175*e5436536SAndroid Build Coastguard Worker 
FDK_MetadataEnc_GetDelay(HANDLE_FDK_METADATA_ENCODER hMetadataEnc)1176*e5436536SAndroid Build Coastguard Worker INT FDK_MetadataEnc_GetDelay(HANDLE_FDK_METADATA_ENCODER hMetadataEnc) {
1177*e5436536SAndroid Build Coastguard Worker   INT delay = 0;
1178*e5436536SAndroid Build Coastguard Worker 
1179*e5436536SAndroid Build Coastguard Worker   if (hMetadataEnc != NULL) {
1180*e5436536SAndroid Build Coastguard Worker     delay = hMetadataEnc->nAudioDataDelay;
1181*e5436536SAndroid Build Coastguard Worker   }
1182*e5436536SAndroid Build Coastguard Worker 
1183*e5436536SAndroid Build Coastguard Worker   return delay;
1184*e5436536SAndroid Build Coastguard Worker }
1185