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