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 FDK_chMapDescr_init(&mapDescrPrev, NULL, 0,
495 (channelOrder == CH_ORDER_MPEG) ? 1 : 0);
496 FDK_chMapDescr_init(&mapDescr, NULL, 0,
497 (channelOrder == CH_ORDER_MPEG) ? 1 : 0);
498
499 switch (channelMode) {
500 case MODE_1:
501 if ((INT)nChannels != 2) {
502 /* preserve center channel */
503 src[0] = FDK_chMapDescr_getMapValue(&mapDescrPrev, 0,
504 hMetaData->channelMode);
505 dst[0] = FDK_chMapDescr_getMapValue(&mapDescr, 0, channelMode);
506 }
507 break;
508 case MODE_2:
509 case MODE_1_2:
510 case MODE_1_2_1:
511 case MODE_1_2_2:
512 case MODE_1_2_2_1:
513 if (hMetaData->nChannels >= 2) {
514 /* preserve left/right channel */
515 src[0] = FDK_chMapDescr_getMapValue(
516 &mapDescrPrev, ((hMetaData->channelMode == 2) ? 0 : 1),
517 hMetaData->channelMode);
518 src[1] = FDK_chMapDescr_getMapValue(
519 &mapDescrPrev, ((hMetaData->channelMode == 2) ? 1 : 2),
520 hMetaData->channelMode);
521 dst[0] = FDK_chMapDescr_getMapValue(
522 &mapDescr, ((channelMode == 2) ? 0 : 1), channelMode);
523 dst[1] = FDK_chMapDescr_getMapValue(
524 &mapDescr, ((channelMode == 2) ? 1 : 2), channelMode);
525 }
526 break;
527 default:;
528 }
529 C_ALLOC_SCRATCH_START(scratch_audioDelayBuffer, INT_PCM, (8));
530 FDKmemclear(scratch_audioDelayBuffer, (8) * sizeof(INT_PCM));
531
532 i = (hMetaData->nChannels > (INT)nChannels)
533 ? 0
534 : hMetaData->nAudioDataDelay - 1;
535 do {
536 for (c = 0; c < 2; c++) {
537 if (src[c] != -1 && dst[c] != -1) {
538 scratch_audioDelayBuffer[dst[c]] =
539 hMetaData->pAudioDelayBuffer[i * hMetaData->nChannels + src[c]];
540 }
541 }
542 FDKmemcpy(&hMetaData->pAudioDelayBuffer[i * nChannels],
543 scratch_audioDelayBuffer, nChannels * sizeof(INT_PCM));
544 i += (hMetaData->nChannels > (INT)nChannels) ? 1 : -1;
545 } while ((i < hMetaData->nAudioDataDelay) && (i >= 0));
546
547 C_ALLOC_SCRATCH_END(scratch_audioDelayBuffer, INT_PCM, (8));
548 }
549 FDKmemclear(hMetaData->metaDataBuffer, sizeof(hMetaData->metaDataBuffer));
550 hMetaData->metaDataDelayIdx = 0;
551 hMetaData->initializeMetaData =
552 1; /* fill up delay line with first meta data info */
553 } else {
554 /* Enable meta data. */
555 if ((hMetaData->metadataMode == 0) && (metadataMode != 0)) {
556 /* disable meta data in all delay lines */
557 for (i = 0;
558 i < (int)(sizeof(hMetaData->metaDataBuffer) / sizeof(AAC_METADATA));
559 i++) {
560 LoadSubmittedMetadata(&hMetaData->submittedMetaData, nChannels, 0,
561 &hMetaData->metaDataBuffer[i]);
562 }
563 }
564
565 /* Disable meta data.*/
566 if ((hMetaData->metadataMode != 0) && (metadataMode == 0)) {
567 hMetaData->finalizeMetaData = hMetaData->metadataMode;
568 }
569 }
570
571 /* Initialize delay. */
572 hMetaData->nAudioDataDelay = -delay;
573 hMetaData->nMetaDataDelay = nFrames;
574 hMetaData->nChannels = nChannels;
575 hMetaData->channelMode = channelMode;
576 hMetaData->metadataMode = metadataMode;
577
578 /* Initialize compressor. */
579 if ((metadataMode == 1) || (metadataMode == 2)) {
580 if (FDK_DRC_Generator_Initialize(hMetaData->hDrcComp, DRC_NONE, DRC_NONE,
581 frameLength, sampleRate, channelMode,
582 channelOrder, 1) != 0) {
583 err = METADATA_INIT_ERROR;
584 }
585 }
586 bail:
587 return err;
588 }
589
ProcessCompressor(AAC_METADATA * pMetadata,HDRC_COMP hDrcComp,const INT_PCM * const pSamples,const UINT samplesBufSize,const INT nSamples)590 static FDK_METADATA_ERROR ProcessCompressor(AAC_METADATA* pMetadata,
591 HDRC_COMP hDrcComp,
592 const INT_PCM* const pSamples,
593 const UINT samplesBufSize,
594 const INT nSamples) {
595 FDK_METADATA_ERROR err = METADATA_OK;
596
597 INT dynrng, compr;
598 INT dmxGain5, dmxGain2;
599 DRC_PROFILE profileDrc;
600 DRC_PROFILE profileComp;
601
602 if ((pMetadata == NULL) || (hDrcComp == NULL)) {
603 err = METADATA_INVALID_HANDLE;
604 return err;
605 }
606
607 profileDrc = convertProfile(pMetadata->mpegDrc.drc_profile);
608 profileComp = convertProfile(pMetadata->etsiAncData.comp_profile);
609
610 /* first, check if profile is same as last frame
611 * otherwise, update setup */
612 if ((profileDrc != FDK_DRC_Generator_getDrcProfile(hDrcComp)) ||
613 (profileComp != FDK_DRC_Generator_getCompProfile(hDrcComp))) {
614 FDK_DRC_Generator_setDrcProfile(hDrcComp, profileDrc, profileComp);
615 }
616
617 /* Sanity check */
618 if (profileComp == DRC_NONE) {
619 pMetadata->etsiAncData.compression_value = 0x80; /* to ensure no external
620 values will be written
621 if not configured */
622 }
623
624 /* in case of embedding external values, copy this now (limiter may overwrite
625 * them) */
626 dynrng = decodeDynrng(pMetadata->mpegDrc.dyn_rng_ctl[0],
627 pMetadata->mpegDrc.dyn_rng_sgn[0]);
628 compr = decodeCompr(pMetadata->etsiAncData.compression_value);
629
630 dmxGain5 = decodeDynrng(pMetadata->etsiAncData.extAncData.dmx_gain_5_idx,
631 pMetadata->etsiAncData.extAncData.dmx_gain_5_sgn);
632 dmxGain2 = decodeDynrng(pMetadata->etsiAncData.extAncData.dmx_gain_2_idx,
633 pMetadata->etsiAncData.extAncData.dmx_gain_2_sgn);
634
635 /* Call compressor */
636 if (FDK_DRC_Generator_Calc(
637 hDrcComp, pSamples, samplesBufSize,
638 progreflvl2dialnorm(pMetadata->mpegDrc.prog_ref_level),
639 pMetadata->mpegDrc.drc_TargetRefLevel,
640 pMetadata->etsiAncData.comp_TargetRefLevel,
641 dmxTable[pMetadata->centerMixLevel],
642 dmxTable[pMetadata->surroundMixLevel],
643 dmxTable[pMetadata->etsiAncData.extAncData.ext_dmix_a_idx],
644 dmxTable[pMetadata->etsiAncData.extAncData.ext_dmix_b_idx],
645 pMetadata->etsiAncData.extAncData.ext_lfe_downmix_status
646 ? dmxLfeTable[pMetadata->etsiAncData.extAncData.ext_dmix_lfe_idx]
647 : (FIXP_DBL)0,
648 dmxGain5, dmxGain2, &dynrng, &compr) != 0) {
649 err = METADATA_ENCODE_ERROR;
650 goto bail;
651 }
652
653 /* Write DRC values */
654 pMetadata->mpegDrc.drc_band_incr = 0;
655 encodeDynrng(dynrng, pMetadata->mpegDrc.dyn_rng_ctl,
656 pMetadata->mpegDrc.dyn_rng_sgn);
657 pMetadata->etsiAncData.compression_value = encodeCompr(compr);
658
659 bail:
660 return err;
661 }
662
FDK_MetadataEnc_Process(HANDLE_FDK_METADATA_ENCODER hMetaDataEnc,INT_PCM * const pAudioSamples,const UINT audioSamplesBufSize,const INT nAudioSamples,const AACENC_MetaData * const pMetadata,AACENC_EXT_PAYLOAD ** ppMetaDataExtPayload,UINT * nMetaDataExtensions,INT * matrix_mixdown_idx)663 FDK_METADATA_ERROR FDK_MetadataEnc_Process(
664 HANDLE_FDK_METADATA_ENCODER hMetaDataEnc, INT_PCM* const pAudioSamples,
665 const UINT audioSamplesBufSize, const INT nAudioSamples,
666 const AACENC_MetaData* const pMetadata,
667 AACENC_EXT_PAYLOAD** ppMetaDataExtPayload, UINT* nMetaDataExtensions,
668 INT* matrix_mixdown_idx) {
669 FDK_METADATA_ERROR err = METADATA_OK;
670 int metaDataDelayWriteIdx, metaDataDelayReadIdx, metadataMode;
671
672 /* Where to write new meta data info */
673 metaDataDelayWriteIdx = hMetaDataEnc->metaDataDelayIdx;
674
675 /* How to write the data */
676 metadataMode = hMetaDataEnc->metadataMode;
677
678 /* Compensate meta data delay. */
679 hMetaDataEnc->metaDataDelayIdx++;
680 if (hMetaDataEnc->metaDataDelayIdx > hMetaDataEnc->nMetaDataDelay)
681 hMetaDataEnc->metaDataDelayIdx = 0;
682
683 /* Where to read pending meta data info from. */
684 metaDataDelayReadIdx = hMetaDataEnc->metaDataDelayIdx;
685
686 /* Submit new data if available. */
687 if (pMetadata != NULL) {
688 FDKmemcpy(&hMetaDataEnc->submittedMetaData, pMetadata,
689 sizeof(AACENC_MetaData));
690 }
691
692 /* Write one additional frame with default configuration of meta data. Ensure
693 * defined behaviour on decoder side. */
694 if ((hMetaDataEnc->finalizeMetaData != 0) &&
695 (hMetaDataEnc->metadataMode == 0)) {
696 FDKmemcpy(&hMetaDataEnc->submittedMetaData, &defaultMetaDataSetup,
697 sizeof(AACENC_MetaData));
698 metadataMode = hMetaDataEnc->finalizeMetaData;
699 hMetaDataEnc->finalizeMetaData = 0;
700 }
701
702 /* Get last submitted data. */
703 if ((err = LoadSubmittedMetadata(
704 &hMetaDataEnc->submittedMetaData, hMetaDataEnc->nChannels,
705 metadataMode,
706 &hMetaDataEnc->metaDataBuffer[metaDataDelayWriteIdx])) !=
707 METADATA_OK) {
708 goto bail;
709 }
710
711 /* Calculate compressor if necessary and updata meta data info */
712 if ((hMetaDataEnc->metaDataBuffer[metaDataDelayWriteIdx].metadataMode == 1) ||
713 (hMetaDataEnc->metaDataBuffer[metaDataDelayWriteIdx].metadataMode == 2)) {
714 if ((err = ProcessCompressor(
715 &hMetaDataEnc->metaDataBuffer[metaDataDelayWriteIdx],
716 hMetaDataEnc->hDrcComp, pAudioSamples, audioSamplesBufSize,
717 nAudioSamples)) != METADATA_OK) {
718 /* Get last submitted data again. */
719 LoadSubmittedMetadata(
720 &hMetaDataEnc->submittedMetaData, hMetaDataEnc->nChannels,
721 metadataMode, &hMetaDataEnc->metaDataBuffer[metaDataDelayWriteIdx]);
722 }
723 }
724
725 /* Fill up delay line with initial meta data info.*/
726 if ((hMetaDataEnc->initializeMetaData != 0) &&
727 (hMetaDataEnc->metadataMode != 0)) {
728 int i;
729 for (i = 0;
730 i < (int)(sizeof(hMetaDataEnc->metaDataBuffer) / sizeof(AAC_METADATA));
731 i++) {
732 if (i != metaDataDelayWriteIdx) {
733 FDKmemcpy(&hMetaDataEnc->metaDataBuffer[i],
734 &hMetaDataEnc->metaDataBuffer[metaDataDelayWriteIdx],
735 sizeof(hMetaDataEnc->metaDataBuffer[metaDataDelayWriteIdx]));
736 }
737 }
738 hMetaDataEnc->initializeMetaData = 0;
739 }
740
741 /* Convert Meta Data side info to bitstream data. */
742 FDK_ASSERT(metaDataDelayReadIdx < MAX_DELAY_FRAMES);
743 if ((err = WriteMetadataPayload(
744 hMetaDataEnc,
745 &hMetaDataEnc->metaDataBuffer[metaDataDelayReadIdx])) !=
746 METADATA_OK) {
747 goto bail;
748 }
749
750 /* Assign meta data to output */
751 *ppMetaDataExtPayload = hMetaDataEnc->exPayload;
752 *nMetaDataExtensions = hMetaDataEnc->nExtensions;
753 *matrix_mixdown_idx = hMetaDataEnc->matrix_mixdown_idx;
754
755 bail:
756 /* Compensate audio delay, reset err status. */
757 err = CompensateAudioDelay(hMetaDataEnc, pAudioSamples, audioSamplesBufSize,
758 nAudioSamples / hMetaDataEnc->nChannels);
759
760 return err;
761 }
762
CompensateAudioDelay(HANDLE_FDK_METADATA_ENCODER hMetaDataEnc,INT_PCM * const pAudioSamples,const UINT audioSamplesBufSize,const INT nAudioSamples)763 static FDK_METADATA_ERROR CompensateAudioDelay(
764 HANDLE_FDK_METADATA_ENCODER hMetaDataEnc, INT_PCM* const pAudioSamples,
765 const UINT audioSamplesBufSize, const INT nAudioSamples) {
766 FDK_METADATA_ERROR err = METADATA_OK;
767
768 if (hMetaDataEnc->nAudioDataDelay) {
769 C_ALLOC_SCRATCH_START(scratch_audioDelayBuffer, INT_PCM, 1024);
770
771 for (int c = 0; c < hMetaDataEnc->nChannels; c++) {
772 int M = 1024;
773 INT_PCM* pAudioSamples2 = pAudioSamples + c * audioSamplesBufSize;
774 int delayIdx = hMetaDataEnc->nAudioDataDelay;
775
776 do {
777 M = fMin(M, delayIdx);
778 delayIdx -= M;
779
780 FDKmemcpy(&scratch_audioDelayBuffer[0],
781 &pAudioSamples2[(nAudioSamples - M)], sizeof(INT_PCM) * M);
782 FDKmemmove(&pAudioSamples2[M], &pAudioSamples2[0],
783 sizeof(INT_PCM) * (nAudioSamples - M));
784 FDKmemcpy(
785 &pAudioSamples2[0],
786 &hMetaDataEnc->pAudioDelayBuffer[delayIdx +
787 c * hMetaDataEnc->nAudioDataDelay],
788 sizeof(INT_PCM) * M);
789 FDKmemcpy(
790 &hMetaDataEnc->pAudioDelayBuffer[delayIdx +
791 c * hMetaDataEnc->nAudioDataDelay],
792 &scratch_audioDelayBuffer[0], sizeof(INT_PCM) * M);
793
794 } while (delayIdx > 0);
795 }
796
797 C_ALLOC_SCRATCH_END(scratch_audioDelayBuffer, INT_PCM, 1024);
798 }
799
800 return err;
801 }
802
803 /*-----------------------------------------------------------------------------
804
805 functionname: WriteMetadataPayload
806 description: fills anc data and extension payload
807 returns: Error status
808
809 ------------------------------------------------------------------------------*/
WriteMetadataPayload(const HANDLE_FDK_METADATA_ENCODER hMetaData,const AAC_METADATA * const pMetadata)810 static FDK_METADATA_ERROR WriteMetadataPayload(
811 const HANDLE_FDK_METADATA_ENCODER hMetaData,
812 const AAC_METADATA* const pMetadata) {
813 FDK_METADATA_ERROR err = METADATA_OK;
814
815 if ((hMetaData == NULL) || (pMetadata == NULL)) {
816 err = METADATA_INVALID_HANDLE;
817 goto bail;
818 }
819
820 hMetaData->nExtensions = 0;
821 hMetaData->matrix_mixdown_idx = -1;
822
823 if (pMetadata->metadataMode != 0) {
824 /* AAC-DRC */
825 if ((pMetadata->metadataMode == 1) || (pMetadata->metadataMode == 2)) {
826 hMetaData->exPayload[hMetaData->nExtensions].pData =
827 hMetaData->drcInfoPayload;
828 hMetaData->exPayload[hMetaData->nExtensions].dataType = EXT_DYNAMIC_RANGE;
829 hMetaData->exPayload[hMetaData->nExtensions].associatedChElement = -1;
830
831 hMetaData->exPayload[hMetaData->nExtensions].dataSize =
832 WriteDynamicRangeInfoPayload(
833 pMetadata, hMetaData->exPayload[hMetaData->nExtensions].pData);
834
835 hMetaData->nExtensions++;
836 } /* pMetadata->metadataMode==1 || pMetadata->metadataMode==2 */
837
838 /* Matrix Mixdown Coefficient in PCE */
839 if (pMetadata->WritePCEMixDwnIdx) {
840 hMetaData->matrix_mixdown_idx =
841 surmix2matrix_mixdown_idx[pMetadata->surroundMixLevel];
842 }
843
844 /* ETSI TS 101 154 (DVB) - MPEG4 ancillary_data() */
845 if ((pMetadata->metadataMode == 2) ||
846 (pMetadata->metadataMode == 3)) /* MP4_METADATA_MPEG_ETSI */
847 {
848 hMetaData->exPayload[hMetaData->nExtensions].pData =
849 hMetaData->drcDsePayload;
850 hMetaData->exPayload[hMetaData->nExtensions].dataType = EXT_DATA_ELEMENT;
851 hMetaData->exPayload[hMetaData->nExtensions].associatedChElement = -1;
852
853 hMetaData->exPayload[hMetaData->nExtensions].dataSize =
854 WriteEtsiAncillaryDataPayload(
855 pMetadata, hMetaData->exPayload[hMetaData->nExtensions].pData);
856
857 hMetaData->nExtensions++;
858 } /* metadataMode==2 || metadataMode==3 */
859
860 } /* metadataMode != 0 */
861
862 bail:
863 return err;
864 }
865
WriteDynamicRangeInfoPayload(const AAC_METADATA * const pMetadata,UCHAR * const pExtensionPayload)866 static INT WriteDynamicRangeInfoPayload(const AAC_METADATA* const pMetadata,
867 UCHAR* const pExtensionPayload) {
868 const INT pce_tag_present = 0; /* yet fixed setting! */
869 const INT prog_ref_lev_res_bits = 0;
870 INT i, drc_num_bands = 1;
871
872 FDK_BITSTREAM bsWriter;
873 FDKinitBitStream(&bsWriter, pExtensionPayload, 16, 0, BS_WRITER);
874
875 /* dynamic_range_info() */
876 FDKwriteBits(&bsWriter, pce_tag_present, 1); /* pce_tag_present */
877 if (pce_tag_present) {
878 FDKwriteBits(&bsWriter, 0x0, 4); /* pce_instance_tag */
879 FDKwriteBits(&bsWriter, 0x0, 4); /* drc_tag_reserved_bits */
880 }
881
882 /* Exclude channels */
883 FDKwriteBits(&bsWriter, (pMetadata->mpegDrc.excluded_chns_present) ? 1 : 0,
884 1); /* excluded_chns_present*/
885
886 /* Multiband DRC */
887 FDKwriteBits(&bsWriter, (pMetadata->mpegDrc.drc_bands_present) ? 1 : 0,
888 1); /* drc_bands_present */
889 if (pMetadata->mpegDrc.drc_bands_present) {
890 FDKwriteBits(&bsWriter, pMetadata->mpegDrc.drc_band_incr,
891 4); /* drc_band_incr */
892 FDKwriteBits(&bsWriter, pMetadata->mpegDrc.drc_interpolation_scheme,
893 4); /* drc_interpolation_scheme */
894 drc_num_bands += pMetadata->mpegDrc.drc_band_incr;
895 for (i = 0; i < drc_num_bands; i++) {
896 FDKwriteBits(&bsWriter, pMetadata->mpegDrc.drc_band_top[i],
897 8); /* drc_band_top */
898 }
899 }
900
901 /* Program Reference Level */
902 FDKwriteBits(&bsWriter, pMetadata->mpegDrc.prog_ref_level_present,
903 1); /* prog_ref_level_present */
904 if (pMetadata->mpegDrc.prog_ref_level_present) {
905 FDKwriteBits(&bsWriter, pMetadata->mpegDrc.prog_ref_level,
906 7); /* prog_ref_level */
907 FDKwriteBits(&bsWriter, prog_ref_lev_res_bits,
908 1); /* prog_ref_level_reserved_bits */
909 }
910
911 /* DRC Values */
912 for (i = 0; i < drc_num_bands; i++) {
913 FDKwriteBits(&bsWriter, (pMetadata->mpegDrc.dyn_rng_sgn[i]) ? 1 : 0,
914 1); /* dyn_rng_sgn[ */
915 FDKwriteBits(&bsWriter, pMetadata->mpegDrc.dyn_rng_ctl[i],
916 7); /* dyn_rng_ctl */
917 }
918
919 /* return number of valid bits in extension payload. */
920 return FDKgetValidBits(&bsWriter);
921 }
922
WriteEtsiAncillaryDataPayload(const AAC_METADATA * const pMetadata,UCHAR * const pExtensionPayload)923 static INT WriteEtsiAncillaryDataPayload(const AAC_METADATA* const pMetadata,
924 UCHAR* const pExtensionPayload) {
925 FDK_BITSTREAM bsWriter;
926 FDKinitBitStream(&bsWriter, pExtensionPayload, 16, 0, BS_WRITER);
927
928 /* ancillary_data_sync */
929 FDKwriteBits(&bsWriter, 0xBC, 8);
930
931 /* bs_info */
932 FDKwriteBits(&bsWriter, 0x3, 2); /* mpeg_audio_type */
933 FDKwriteBits(&bsWriter, pMetadata->dolbySurroundMode,
934 2); /* dolby_surround_mode */
935 FDKwriteBits(&bsWriter, pMetadata->drcPresentationMode,
936 2); /* DRC presentation mode */
937 FDKwriteBits(&bsWriter, 0x0, 1); /* stereo_downmix_mode */
938 FDKwriteBits(&bsWriter, 0x0, 1); /* reserved */
939
940 /* ancillary_data_status */
941 FDKwriteBits(&bsWriter, 0, 3); /* 3 bit Reserved, set to "0" */
942 FDKwriteBits(&bsWriter, (pMetadata->DmxLvl_On) ? 1 : 0,
943 1); /* downmixing_levels_MPEG4_status */
944 FDKwriteBits(&bsWriter, pMetadata->etsiAncData.extAncDataStatus,
945 1); /* ext_anc_data_status */
946 FDKwriteBits(&bsWriter, (pMetadata->etsiAncData.compression_on) ? 1 : 0,
947 1); /* audio_coding_mode_and_compression status */
948 FDKwriteBits(&bsWriter,
949 (pMetadata->etsiAncData.timecode_coarse_status) ? 1 : 0,
950 1); /* coarse_grain_timecode_status */
951 FDKwriteBits(&bsWriter, (pMetadata->etsiAncData.timecode_fine_status) ? 1 : 0,
952 1); /* fine_grain_timecode_status */
953
954 /* downmixing_levels_MPEG4_status */
955 if (pMetadata->DmxLvl_On) {
956 FDKwriteBits(
957 &bsWriter,
958 encodeDmxLvls(pMetadata->centerMixLevel, pMetadata->surroundMixLevel),
959 8);
960 }
961
962 /* audio_coding_mode_and_compression_status */
963 if (pMetadata->etsiAncData.compression_on) {
964 FDKwriteBits(&bsWriter, 0x01, 8); /* audio coding mode */
965 FDKwriteBits(&bsWriter, pMetadata->etsiAncData.compression_value,
966 8); /* compression value */
967 }
968
969 /* grain-timecode coarse/fine */
970 if (pMetadata->etsiAncData.timecode_coarse_status) {
971 FDKwriteBits(&bsWriter, 0x0, 16); /* not yet supported */
972 }
973
974 if (pMetadata->etsiAncData.timecode_fine_status) {
975 FDKwriteBits(&bsWriter, 0x0, 16); /* not yet supported */
976 }
977
978 /* extended ancillary data structure */
979 if (pMetadata->etsiAncData.extAncDataStatus) {
980 /* ext_ancillary_data_status */
981 FDKwriteBits(&bsWriter, 0, 1); /* Reserved, set to "0" */
982 FDKwriteBits(&bsWriter,
983 pMetadata->etsiAncData.extAncData.ext_downmix_lvl_status,
984 1); /* ext_downmixing_levels_status */
985 FDKwriteBits(&bsWriter,
986 pMetadata->etsiAncData.extAncData.ext_downmix_gain_status,
987 1); /* ext_downmixing_global_gains_status */
988 FDKwriteBits(&bsWriter,
989 pMetadata->etsiAncData.extAncData.ext_lfe_downmix_status,
990 1); /* ext_downmixing_lfe_level_status" */
991 FDKwriteBits(&bsWriter, 0, 4); /* Reserved, set to "0" */
992
993 /* ext_downmixing_levels */
994 if (pMetadata->etsiAncData.extAncData.ext_downmix_lvl_status) {
995 FDKwriteBits(&bsWriter, pMetadata->etsiAncData.extAncData.ext_dmix_a_idx,
996 3); /* dmix_a_idx */
997 FDKwriteBits(&bsWriter, pMetadata->etsiAncData.extAncData.ext_dmix_b_idx,
998 3); /* dmix_b_idx */
999 FDKwriteBits(&bsWriter, 0, 2); /* Reserved, set to "0" */
1000 }
1001
1002 /* ext_downmixing_gains */
1003 if (pMetadata->etsiAncData.extAncData.ext_downmix_gain_status) {
1004 FDKwriteBits(&bsWriter, pMetadata->etsiAncData.extAncData.dmx_gain_5_sgn,
1005 1); /* dmx_gain_5_sign */
1006 FDKwriteBits(&bsWriter, pMetadata->etsiAncData.extAncData.dmx_gain_5_idx,
1007 6); /* dmx_gain_5_idx */
1008 FDKwriteBits(&bsWriter, 0, 1); /* Reserved, set to "0" */
1009 FDKwriteBits(&bsWriter, pMetadata->etsiAncData.extAncData.dmx_gain_2_sgn,
1010 1); /* dmx_gain_2_sign */
1011 FDKwriteBits(&bsWriter, pMetadata->etsiAncData.extAncData.dmx_gain_2_idx,
1012 6); /* dmx_gain_2_idx */
1013 FDKwriteBits(&bsWriter, 0, 1); /* Reserved, set to "0" */
1014 }
1015
1016 if (pMetadata->etsiAncData.extAncData.ext_lfe_downmix_status) {
1017 FDKwriteBits(&bsWriter,
1018 pMetadata->etsiAncData.extAncData.ext_dmix_lfe_idx,
1019 4); /* dmix_lfe_idx */
1020 FDKwriteBits(&bsWriter, 0, 4); /* Reserved, set to "0" */
1021 }
1022 }
1023
1024 return FDKgetValidBits(&bsWriter);
1025 }
1026
LoadSubmittedMetadata(const AACENC_MetaData * const hMetadata,const INT nChannels,const INT metadataMode,AAC_METADATA * const pAacMetaData)1027 static FDK_METADATA_ERROR LoadSubmittedMetadata(
1028 const AACENC_MetaData* const hMetadata, const INT nChannels,
1029 const INT metadataMode, AAC_METADATA* const pAacMetaData) {
1030 FDK_METADATA_ERROR err = METADATA_OK;
1031
1032 if (pAacMetaData == NULL) {
1033 err = METADATA_INVALID_HANDLE;
1034 } else {
1035 /* init struct */
1036 FDKmemclear(pAacMetaData, sizeof(AAC_METADATA));
1037
1038 if (hMetadata != NULL) {
1039 /* convert data */
1040 pAacMetaData->mpegDrc.drc_profile = hMetadata->drc_profile;
1041 pAacMetaData->etsiAncData.comp_profile = hMetadata->comp_profile;
1042 pAacMetaData->mpegDrc.drc_TargetRefLevel = hMetadata->drc_TargetRefLevel;
1043 pAacMetaData->etsiAncData.comp_TargetRefLevel =
1044 hMetadata->comp_TargetRefLevel;
1045 pAacMetaData->mpegDrc.prog_ref_level_present =
1046 hMetadata->prog_ref_level_present;
1047 pAacMetaData->mpegDrc.prog_ref_level =
1048 dialnorm2progreflvl(hMetadata->prog_ref_level);
1049
1050 pAacMetaData->centerMixLevel = hMetadata->centerMixLevel;
1051 pAacMetaData->surroundMixLevel = hMetadata->surroundMixLevel;
1052 pAacMetaData->WritePCEMixDwnIdx = hMetadata->PCE_mixdown_idx_present;
1053 pAacMetaData->DmxLvl_On = hMetadata->ETSI_DmxLvl_present;
1054
1055 pAacMetaData->etsiAncData.compression_on =
1056 (hMetadata->comp_profile == AACENC_METADATA_DRC_NOT_PRESENT ? 0 : 1);
1057
1058 if (pAacMetaData->mpegDrc.drc_profile ==
1059 AACENC_METADATA_DRC_NOT_PRESENT) {
1060 pAacMetaData->mpegDrc.drc_profile =
1061 AACENC_METADATA_DRC_NONE; /* MPEG DRC gains are
1062 always present in BS
1063 syntax */
1064 /* we should give a warning, but ErrorHandler does not support this */
1065 }
1066
1067 if (nChannels == 2) {
1068 pAacMetaData->dolbySurroundMode =
1069 hMetadata->dolbySurroundMode; /* dolby_surround_mode */
1070 } else {
1071 pAacMetaData->dolbySurroundMode = 0;
1072 }
1073
1074 pAacMetaData->drcPresentationMode = hMetadata->drcPresentationMode;
1075 /* override external values if DVB DRC presentation mode is given */
1076 if (pAacMetaData->drcPresentationMode == 1) {
1077 pAacMetaData->mpegDrc.drc_TargetRefLevel =
1078 fMax(-(31 << 16), pAacMetaData->mpegDrc.drc_TargetRefLevel);
1079 pAacMetaData->etsiAncData.comp_TargetRefLevel = fMax(
1080 -(20 << 16),
1081 pAacMetaData->etsiAncData.comp_TargetRefLevel); /* implies -23dB */
1082 }
1083 if (pAacMetaData->drcPresentationMode == 2) {
1084 pAacMetaData->mpegDrc.drc_TargetRefLevel =
1085 fMax(-(23 << 16), pAacMetaData->mpegDrc.drc_TargetRefLevel);
1086 pAacMetaData->etsiAncData.comp_TargetRefLevel =
1087 fMax(-(23 << 16), pAacMetaData->etsiAncData.comp_TargetRefLevel);
1088 }
1089 if (pAacMetaData->etsiAncData.comp_profile ==
1090 AACENC_METADATA_DRC_NOT_PRESENT) {
1091 /* DVB defines to revert to Light DRC if heavy is not present */
1092 if (pAacMetaData->drcPresentationMode != 0) {
1093 /* we exclude the "not indicated" mode as this requires the user to
1094 * define desired levels anyway */
1095 pAacMetaData->mpegDrc.drc_TargetRefLevel =
1096 fMax(pAacMetaData->etsiAncData.comp_TargetRefLevel,
1097 pAacMetaData->mpegDrc.drc_TargetRefLevel);
1098 }
1099 }
1100
1101 pAacMetaData->etsiAncData.timecode_coarse_status =
1102 0; /* not yet supported - attention: Update
1103 GetEstMetadataBytesPerFrame() if enable this! */
1104 pAacMetaData->etsiAncData.timecode_fine_status =
1105 0; /* not yet supported - attention: Update
1106 GetEstMetadataBytesPerFrame() if enable this! */
1107
1108 /* extended ancillary data */
1109 pAacMetaData->etsiAncData.extAncDataStatus =
1110 ((hMetadata->ExtMetaData.extAncDataEnable == 1) ? 1 : 0);
1111
1112 if (pAacMetaData->etsiAncData.extAncDataStatus) {
1113 pAacMetaData->etsiAncData.extAncData.ext_downmix_lvl_status =
1114 (hMetadata->ExtMetaData.extDownmixLevelEnable ? 1 : 0);
1115 pAacMetaData->etsiAncData.extAncData.ext_downmix_gain_status =
1116 (hMetadata->ExtMetaData.dmxGainEnable ? 1 : 0);
1117 pAacMetaData->etsiAncData.extAncData.ext_lfe_downmix_status =
1118 (hMetadata->ExtMetaData.lfeDmxEnable ? 1 : 0);
1119
1120 pAacMetaData->etsiAncData.extAncData.ext_dmix_a_idx =
1121 hMetadata->ExtMetaData.extDownmixLevel_A;
1122 pAacMetaData->etsiAncData.extAncData.ext_dmix_b_idx =
1123 hMetadata->ExtMetaData.extDownmixLevel_B;
1124
1125 if (pAacMetaData->etsiAncData.extAncData.ext_downmix_gain_status) {
1126 encodeDynrng(hMetadata->ExtMetaData.dmxGain5,
1127 &(pAacMetaData->etsiAncData.extAncData.dmx_gain_5_idx),
1128 &(pAacMetaData->etsiAncData.extAncData.dmx_gain_5_sgn));
1129 encodeDynrng(hMetadata->ExtMetaData.dmxGain2,
1130 &(pAacMetaData->etsiAncData.extAncData.dmx_gain_2_idx),
1131 &(pAacMetaData->etsiAncData.extAncData.dmx_gain_2_sgn));
1132 } else {
1133 encodeDynrng(1 << 16,
1134 &(pAacMetaData->etsiAncData.extAncData.dmx_gain_5_idx),
1135 &(pAacMetaData->etsiAncData.extAncData.dmx_gain_5_sgn));
1136 encodeDynrng(1 << 16,
1137 &(pAacMetaData->etsiAncData.extAncData.dmx_gain_2_idx),
1138 &(pAacMetaData->etsiAncData.extAncData.dmx_gain_2_sgn));
1139 }
1140
1141 if (pAacMetaData->etsiAncData.extAncData.ext_lfe_downmix_status) {
1142 pAacMetaData->etsiAncData.extAncData.ext_dmix_lfe_idx =
1143 hMetadata->ExtMetaData.lfeDmxLevel;
1144 } else {
1145 pAacMetaData->etsiAncData.extAncData.ext_dmix_lfe_idx =
1146 15; /* -inf dB */
1147 }
1148 } else {
1149 pAacMetaData->etsiAncData.extAncData.ext_downmix_lvl_status = 0;
1150 pAacMetaData->etsiAncData.extAncData.ext_downmix_gain_status = 0;
1151 pAacMetaData->etsiAncData.extAncData.ext_lfe_downmix_status = 0;
1152
1153 pAacMetaData->etsiAncData.extAncData.ext_dmix_a_idx = 7; /* -inf dB */
1154 pAacMetaData->etsiAncData.extAncData.ext_dmix_b_idx = 7; /* -inf dB */
1155
1156 encodeDynrng(1 << 16,
1157 &(pAacMetaData->etsiAncData.extAncData.dmx_gain_5_idx),
1158 &(pAacMetaData->etsiAncData.extAncData.dmx_gain_5_sgn));
1159 encodeDynrng(1 << 16,
1160 &(pAacMetaData->etsiAncData.extAncData.dmx_gain_2_idx),
1161 &(pAacMetaData->etsiAncData.extAncData.dmx_gain_2_sgn));
1162
1163 pAacMetaData->etsiAncData.extAncData.ext_dmix_lfe_idx =
1164 15; /* -inf dB */
1165 }
1166
1167 pAacMetaData->metadataMode = metadataMode;
1168 } else {
1169 pAacMetaData->metadataMode = 0; /* there is no configuration available */
1170 }
1171 }
1172
1173 return err;
1174 }
1175
FDK_MetadataEnc_GetDelay(HANDLE_FDK_METADATA_ENCODER hMetadataEnc)1176 INT FDK_MetadataEnc_GetDelay(HANDLE_FDK_METADATA_ENCODER hMetadataEnc) {
1177 INT delay = 0;
1178
1179 if (hMetadataEnc != NULL) {
1180 delay = hMetadataEnc->nAudioDataDelay;
1181 }
1182
1183 return delay;
1184 }
1185