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