1
2 /* -----------------------------------------------------------------------------------------------------------
3 Software License for The Fraunhofer FDK AAC Codec Library for Android
4
5 � Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur F�rderung der angewandten Forschung e.V.
6 All rights reserved.
7
8 1. INTRODUCTION
9 The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements
10 the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio.
11 This FDK AAC Codec software is intended to be used on a wide variety of Android devices.
12
13 AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual
14 audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by
15 independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part
16 of the MPEG specifications.
17
18 Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer)
19 may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners
20 individually for the purpose of encoding or decoding bit streams in products that are compliant with
21 the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license
22 these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec
23 software may already be covered under those patent licenses when it is used for those licensed purposes only.
24
25 Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality,
26 are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional
27 applications information and documentation.
28
29 2. COPYRIGHT LICENSE
30
31 Redistribution and use in source and binary forms, with or without modification, are permitted without
32 payment of copyright license fees provided that you satisfy the following conditions:
33
34 You must retain the complete text of this software license in redistributions of the FDK AAC Codec or
35 your modifications thereto in source code form.
36
37 You must retain the complete text of this software license in the documentation and/or other materials
38 provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form.
39 You must make available free of charge copies of the complete source code of the FDK AAC Codec and your
40 modifications thereto to recipients of copies in binary form.
41
42 The name of Fraunhofer may not be used to endorse or promote products derived from this library without
43 prior written permission.
44
45 You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec
46 software or your modifications thereto.
47
48 Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software
49 and the date of any change. For modified versions of the FDK AAC Codec, the term
50 "Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term
51 "Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android."
52
53 3. NO PATENT LICENSE
54
55 NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer,
56 ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with
57 respect to this software.
58
59 You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized
60 by appropriate patent licenses.
61
62 4. DISCLAIMER
63
64 This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors
65 "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties
66 of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
67 CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages,
68 including but not limited to procurement of substitute goods or services; loss of use, data, or profits,
69 or business interruption, however caused and on any theory of liability, whether in contract, strict
70 liability, or tort (including negligence), arising in any way out of the use of this software, even if
71 advised of the possibility of such damage.
72
73 5. CONTACT INFORMATION
74
75 Fraunhofer Institute for Integrated Circuits IIS
76 Attention: Audio and Multimedia Departments - FDK AAC LL
77 Am Wolfsmantel 33
78 91058 Erlangen, Germany
79
80 www.iis.fraunhofer.de/amm
81 amm-info@iis.fraunhofer.de
82 ----------------------------------------------------------------------------------------------------------- */
83
84 /********************** Fraunhofer IIS FDK AAC Encoder lib ******************
85
86 Author(s): V. Bacigalupo
87 Description: Metadata Encoder library interface functions
88
89 ******************************************************************************/
90
91
92 #include "metadata_main.h"
93 #include "metadata_compressor.h"
94 #include "FDK_bitstream.h"
95 #include "FDK_audio.h"
96 #include "genericStds.h"
97
98 /*----------------- defines ----------------------*/
99 #define MAX_DRC_BANDS (1<<4)
100 #define MAX_DRC_CHANNELS (8)
101 #define MAX_DRC_FRAMELEN (2*1024)
102
103 /*--------------- structure definitions --------------------*/
104
105 typedef struct AAC_METADATA
106 {
107 /* MPEG: Dynamic Range Control */
108 struct {
109 UCHAR prog_ref_level_present;
110 SCHAR prog_ref_level;
111
112 UCHAR dyn_rng_sgn[MAX_DRC_BANDS];
113 UCHAR dyn_rng_ctl[MAX_DRC_BANDS];
114
115 UCHAR drc_bands_present;
116 UCHAR drc_band_incr;
117 UCHAR drc_band_top[MAX_DRC_BANDS];
118 UCHAR drc_interpolation_scheme;
119 AACENC_METADATA_DRC_PROFILE drc_profile;
120 INT drc_TargetRefLevel; /* used for Limiter */
121
122 /* excluded channels */
123 UCHAR excluded_chns_present;
124 UCHAR exclude_mask[2]; /* MAX_NUMBER_CHANNELS/8 */
125 } mpegDrc;
126
127 /* ETSI: addtl ancillary data */
128 struct {
129 /* Heavy Compression */
130 UCHAR compression_on; /* flag, if compression value should be written */
131 UCHAR compression_value; /* compression value */
132 AACENC_METADATA_DRC_PROFILE comp_profile;
133 INT comp_TargetRefLevel; /* used for Limiter */
134 INT timecode_coarse_status;
135 INT timecode_fine_status;
136 } etsiAncData;
137
138 SCHAR centerMixLevel; /* center downmix level (0...7, according to table) */
139 SCHAR surroundMixLevel; /* surround downmix level (0...7, according to table) */
140 UCHAR WritePCEMixDwnIdx; /* flag */
141 UCHAR DmxLvl_On; /* flag */
142
143 UCHAR dolbySurroundMode;
144
145 UCHAR metadataMode; /* indicate meta data mode in current frame (delay line) */
146
147 } AAC_METADATA;
148
149 struct FDK_METADATA_ENCODER
150 {
151 INT metadataMode;
152 HDRC_COMP hDrcComp;
153 AACENC_MetaData submittedMetaData;
154
155 INT nAudioDataDelay;
156 INT nMetaDataDelay;
157 INT nChannels;
158
159 INT_PCM audioDelayBuffer[MAX_DRC_CHANNELS*MAX_DRC_FRAMELEN];
160 int audioDelayIdx;
161
162 AAC_METADATA metaDataBuffer[3];
163 int metaDataDelayIdx;
164
165 UCHAR drcInfoPayload[12];
166 UCHAR drcDsePayload[8];
167
168 INT matrix_mixdown_idx;
169 AACENC_EXT_PAYLOAD exPayload[2];
170 INT nExtensions;
171
172 INT finalizeMetaData; /* Delay switch off by one frame and write default configuration to
173 finalize the metadata setup. */
174 };
175
176
177 /*---------------- constants -----------------------*/
178 static const AACENC_MetaData defaultMetaDataSetup = {
179 AACENC_METADATA_DRC_NONE,
180 AACENC_METADATA_DRC_NONE,
181 -(31<<16),
182 -(31<<16),
183 0,
184 -(31<<16),
185 0,
186 0,
187 0,
188 0,
189 0
190 };
191
192 static const FIXP_DBL dmxTable[8] = {
193 ((FIXP_DBL)MAXVAL_DBL), FL2FXCONST_DBL(0.841f), FL2FXCONST_DBL(0.707f), FL2FXCONST_DBL(0.596f),
194 FL2FXCONST_DBL(0.500f), FL2FXCONST_DBL(0.422f), FL2FXCONST_DBL(0.355f), FL2FXCONST_DBL(0.000f)
195 };
196
197 static const UCHAR surmix2matrix_mixdown_idx[8] = {
198 0, 0, 0, 1, 1, 2, 2, 3
199 };
200
201
202 /*--------------- function declarations --------------------*/
203 static FDK_METADATA_ERROR WriteMetadataPayload(
204 const HANDLE_FDK_METADATA_ENCODER hMetaData,
205 const AAC_METADATA * const pMetadata
206 );
207
208 static INT WriteDynamicRangeInfoPayload(
209 const AAC_METADATA* const pMetadata,
210 UCHAR* const pExtensionPayload
211 );
212
213 static INT WriteEtsiAncillaryDataPayload(
214 const AAC_METADATA* const pMetadata,
215 UCHAR* const pExtensionPayload
216 );
217
218 static FDK_METADATA_ERROR CompensateAudioDelay(
219 HANDLE_FDK_METADATA_ENCODER hMetaDataEnc,
220 INT_PCM * const pAudioSamples,
221 const INT nAudioSamples
222 );
223
224 static FDK_METADATA_ERROR LoadSubmittedMetadata(
225 const AACENC_MetaData * const hMetadata,
226 const INT nChannels,
227 const INT metadataMode,
228 AAC_METADATA * const pAacMetaData
229 );
230
231 static FDK_METADATA_ERROR ProcessCompressor(
232 AAC_METADATA *pMetadata,
233 HDRC_COMP hDrcComp,
234 const INT_PCM * const pSamples,
235 const INT nSamples
236 );
237
238 /*------------- function definitions ----------------*/
239
convertProfile(AACENC_METADATA_DRC_PROFILE aacProfile)240 static DRC_PROFILE convertProfile(AACENC_METADATA_DRC_PROFILE aacProfile)
241 {
242 DRC_PROFILE drcProfile = DRC_NONE;
243
244 switch(aacProfile) {
245 case AACENC_METADATA_DRC_NONE: drcProfile = DRC_NONE; break;
246 case AACENC_METADATA_DRC_FILMSTANDARD: drcProfile = DRC_FILMSTANDARD; break;
247 case AACENC_METADATA_DRC_FILMLIGHT: drcProfile = DRC_FILMLIGHT; break;
248 case AACENC_METADATA_DRC_MUSICSTANDARD: drcProfile = DRC_MUSICSTANDARD; break;
249 case AACENC_METADATA_DRC_MUSICLIGHT: drcProfile = DRC_MUSICLIGHT; break;
250 case AACENC_METADATA_DRC_SPEECH: drcProfile = DRC_SPEECH; break;
251 default: drcProfile = DRC_NONE; break;
252 }
253 return drcProfile;
254 }
255
256
257 /* convert dialog normalization to program reference level */
258 /* NOTE: this only is correct, if the decoder target level is set to -31dB for line mode / -20dB for RF mode */
dialnorm2progreflvl(const INT d)259 static UCHAR dialnorm2progreflvl(const INT d)
260 {
261 return ((UCHAR)FDKmax(0, FDKmin((-d + (1<<13)) >> 14, 127)));
262 }
263
264 /* convert program reference level to dialog normalization */
progreflvl2dialnorm(const UCHAR p)265 static INT progreflvl2dialnorm(const UCHAR p)
266 {
267 return -((INT)(p<<(16-2)));
268 }
269
270 /* encode downmix levels to Downmixing_levels_MPEG4 */
encodeDmxLvls(const SCHAR cmixlev,const SCHAR surmixlev)271 static SCHAR encodeDmxLvls(const SCHAR cmixlev, const SCHAR surmixlev)
272 {
273 SCHAR dmxLvls = 0;
274 dmxLvls |= 0x80 | (cmixlev << 4); /* center_mix_level_on */
275 dmxLvls |= 0x08 | surmixlev; /* surround_mix_level_on */
276
277 return dmxLvls;
278 }
279
280 /* 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)281 static void encodeDynrng(INT gain, UCHAR* const dyn_rng_ctl, UCHAR* const dyn_rng_sgn )
282 {
283 if(gain < 0)
284 {
285 *dyn_rng_sgn = 1;
286 gain = -gain;
287 }
288 else
289 {
290 *dyn_rng_sgn = 0;
291 }
292 gain = FDKmin(gain,(127<<14));
293
294 *dyn_rng_ctl = (UCHAR)((gain + (1<<13)) >> 14);
295 }
296
297 /* decode AAC DRC gain (ISO/IEC 14496-3:2005 4.5.2.7) */
decodeDynrng(const UCHAR dyn_rng_ctl,const UCHAR dyn_rng_sgn)298 static INT decodeDynrng(const UCHAR dyn_rng_ctl, const UCHAR dyn_rng_sgn)
299 {
300 INT tmp = ((INT)dyn_rng_ctl << (16-2));
301 if (dyn_rng_sgn) tmp = -tmp;
302
303 return tmp;
304 }
305
306 /* encode AAC compression value (ETSI TS 101 154 page 99) */
encodeCompr(INT gain)307 static UCHAR encodeCompr(INT gain)
308 {
309 UCHAR x, y;
310 INT tmp;
311
312 /* tmp = (int)((48.164f - gain) / 6.0206f * 15 + 0.5f); */
313 tmp = ((3156476 - gain) * 15 + 197283) / 394566;
314
315 if (tmp >= 240) {
316 return 0xFF;
317 }
318 else if (tmp < 0) {
319 return 0;
320 }
321 else {
322 x = tmp / 15;
323 y = tmp % 15;
324 }
325
326 return (x << 4) | y;
327 }
328
329 /* decode AAC compression value (ETSI TS 101 154 page 99) */
decodeCompr(const UCHAR compr)330 static INT decodeCompr(const UCHAR compr)
331 {
332 INT gain;
333 SCHAR x = compr >> 4; /* 4 MSB of compr */
334 UCHAR y = (compr & 0x0F); /* 4 LSB of compr */
335
336 /* gain = (INT)((48.164f - 6.0206f * x - 0.4014f * y) ); */
337 gain = (INT)( scaleValue(((LONG)FL2FXCONST_DBL(6.0206f/128.f)*(8-x) - (LONG)FL2FXCONST_DBL(0.4014f/128.f)*y), -(DFRACT_BITS-1-7-16)) );
338
339 return gain;
340 }
341
342
FDK_MetadataEnc_Open(HANDLE_FDK_METADATA_ENCODER * phMetaData)343 FDK_METADATA_ERROR FDK_MetadataEnc_Open(
344 HANDLE_FDK_METADATA_ENCODER *phMetaData
345 )
346 {
347 FDK_METADATA_ERROR err = METADATA_OK;
348 HANDLE_FDK_METADATA_ENCODER hMetaData = NULL;
349
350 if (phMetaData == NULL) {
351 err = METADATA_INVALID_HANDLE;
352 goto bail;
353 }
354
355 /* allocate memory */
356 hMetaData = (HANDLE_FDK_METADATA_ENCODER) FDKcalloc(1, sizeof(FDK_METADATA_ENCODER) );
357
358 if (hMetaData == NULL) {
359 err = METADATA_MEMORY_ERROR;
360 goto bail;
361 }
362
363 FDKmemclear(hMetaData, sizeof(FDK_METADATA_ENCODER));
364
365 /* Allocate DRC Compressor. */
366 if (FDK_DRC_Generator_Open(&hMetaData->hDrcComp)!=0) {
367 err = METADATA_MEMORY_ERROR;
368 goto bail;
369 }
370
371 /* Return metadata instance */
372 *phMetaData = hMetaData;
373
374 return err;
375
376 bail:
377 FDK_MetadataEnc_Close(&hMetaData);
378 return err;
379 }
380
FDK_MetadataEnc_Close(HANDLE_FDK_METADATA_ENCODER * phMetaData)381 FDK_METADATA_ERROR FDK_MetadataEnc_Close(
382 HANDLE_FDK_METADATA_ENCODER *phMetaData
383 )
384 {
385 FDK_METADATA_ERROR err = METADATA_OK;
386
387 if (phMetaData == NULL) {
388 err = METADATA_INVALID_HANDLE;
389 goto bail;
390 }
391
392 if (*phMetaData != NULL) {
393 FDK_DRC_Generator_Close(&(*phMetaData)->hDrcComp);
394 FDKfree(*phMetaData);
395 *phMetaData = NULL;
396 }
397 bail:
398 return err;
399 }
400
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)401 FDK_METADATA_ERROR FDK_MetadataEnc_Init(
402 HANDLE_FDK_METADATA_ENCODER hMetaData,
403 const INT resetStates,
404 const INT metadataMode,
405 const INT audioDelay,
406 const UINT frameLength,
407 const UINT sampleRate,
408 const UINT nChannels,
409 const CHANNEL_MODE channelMode,
410 const CHANNEL_ORDER channelOrder
411 )
412 {
413 FDK_METADATA_ERROR err = METADATA_OK;
414 int i, nFrames, delay;
415
416 if (hMetaData==NULL) {
417 err = METADATA_INVALID_HANDLE;
418 goto bail;
419 }
420
421 /* Determine values for delay compensation. */
422 for (nFrames=0, delay=audioDelay-frameLength; delay>0; delay-=frameLength, nFrames++);
423
424 if ( (hMetaData->nChannels>MAX_DRC_CHANNELS) || ((-delay)>MAX_DRC_FRAMELEN) ) {
425 err = METADATA_INIT_ERROR;
426 goto bail;
427 }
428
429 /* Initialize with default setup. */
430 FDKmemcpy(&hMetaData->submittedMetaData, &defaultMetaDataSetup, sizeof(AACENC_MetaData));
431
432 hMetaData->finalizeMetaData = 0; /* finalize meta data only while on/off switching, else disabled */
433
434 /* Reset delay lines. */
435 if ( resetStates || (hMetaData->nAudioDataDelay!=-delay) || (hMetaData->nChannels!=(INT)nChannels) )
436 {
437 FDKmemclear(hMetaData->audioDelayBuffer, sizeof(hMetaData->audioDelayBuffer));
438 FDKmemclear(hMetaData->metaDataBuffer, sizeof(hMetaData->metaDataBuffer));
439 hMetaData->audioDelayIdx = 0;
440 hMetaData->metaDataDelayIdx = 0;
441 }
442 else {
443 /* Enable meta data. */
444 if ( (hMetaData->metadataMode==0) && (metadataMode!=0) ) {
445 /* disable meta data in all delay lines */
446 for (i=0; i<(int)(sizeof(hMetaData->metaDataBuffer)/sizeof(AAC_METADATA)); i++) {
447 LoadSubmittedMetadata(&hMetaData->submittedMetaData, nChannels, 0, &hMetaData->metaDataBuffer[i]);
448 }
449 }
450
451 /* Disable meta data.*/
452 if ( (hMetaData->metadataMode!=0) && (metadataMode==0) ) {
453 hMetaData->finalizeMetaData = hMetaData->metadataMode;
454 }
455 }
456
457 /* Initialize delay. */
458 hMetaData->nAudioDataDelay = -delay;
459 hMetaData->nMetaDataDelay = nFrames;
460 hMetaData->nChannels = nChannels;
461 hMetaData->metadataMode = metadataMode;
462
463 /* Initialize compressor. */
464 if (metadataMode != 0) {
465 if ( FDK_DRC_Generator_Initialize(
466 hMetaData->hDrcComp,
467 DRC_NONE,
468 DRC_NONE,
469 frameLength,
470 sampleRate,
471 channelMode,
472 channelOrder,
473 1) != 0)
474 {
475 err = METADATA_INIT_ERROR;
476 }
477 }
478 bail:
479 return err;
480 }
481
ProcessCompressor(AAC_METADATA * pMetadata,HDRC_COMP hDrcComp,const INT_PCM * const pSamples,const INT nSamples)482 static FDK_METADATA_ERROR ProcessCompressor(
483 AAC_METADATA *pMetadata,
484 HDRC_COMP hDrcComp,
485 const INT_PCM * const pSamples,
486 const INT nSamples
487 )
488 {
489 FDK_METADATA_ERROR err = METADATA_OK;
490
491 if ( (pMetadata==NULL) || (hDrcComp==NULL) ) {
492 err = METADATA_INVALID_HANDLE;
493 return err;
494 }
495 DRC_PROFILE profileDrc = convertProfile(pMetadata->mpegDrc.drc_profile);
496 DRC_PROFILE profileComp = convertProfile(pMetadata->etsiAncData.comp_profile);
497
498 /* first, check if profile is same as last frame
499 * otherwise, update setup */
500 if ( (profileDrc != FDK_DRC_Generator_getDrcProfile(hDrcComp))
501 || (profileComp != FDK_DRC_Generator_getCompProfile(hDrcComp)) )
502 {
503 FDK_DRC_Generator_setDrcProfile(hDrcComp, profileDrc, profileComp);
504 }
505
506 /* Sanity check */
507 if (profileComp == DRC_NONE) {
508 pMetadata->etsiAncData.compression_value = 0x80; /* to ensure no external values will be written if not configured */
509 }
510
511 /* in case of embedding external values, copy this now (limiter may overwrite them) */
512 INT dynrng = decodeDynrng(pMetadata->mpegDrc.dyn_rng_ctl[0], pMetadata->mpegDrc.dyn_rng_sgn[0]);
513 INT compr = decodeCompr(pMetadata->etsiAncData.compression_value);
514
515 /* Call compressor */
516 if (FDK_DRC_Generator_Calc(hDrcComp,
517 pSamples,
518 progreflvl2dialnorm(pMetadata->mpegDrc.prog_ref_level),
519 pMetadata->mpegDrc.drc_TargetRefLevel,
520 pMetadata->etsiAncData.comp_TargetRefLevel,
521 dmxTable[pMetadata->centerMixLevel],
522 dmxTable[pMetadata->surroundMixLevel],
523 &dynrng,
524 &compr) != 0)
525 {
526 err = METADATA_ENCODE_ERROR;
527 goto bail;
528 }
529
530 /* Write DRC values */
531 pMetadata->mpegDrc.drc_band_incr = 0;
532 encodeDynrng(dynrng, pMetadata->mpegDrc.dyn_rng_ctl, pMetadata->mpegDrc.dyn_rng_sgn);
533 pMetadata->etsiAncData.compression_value = encodeCompr(compr);
534
535 bail:
536 return err;
537 }
538
FDK_MetadataEnc_Process(HANDLE_FDK_METADATA_ENCODER hMetaDataEnc,INT_PCM * const pAudioSamples,const INT nAudioSamples,const AACENC_MetaData * const pMetadata,AACENC_EXT_PAYLOAD ** ppMetaDataExtPayload,UINT * nMetaDataExtensions,INT * matrix_mixdown_idx)539 FDK_METADATA_ERROR FDK_MetadataEnc_Process(
540 HANDLE_FDK_METADATA_ENCODER hMetaDataEnc,
541 INT_PCM * const pAudioSamples,
542 const INT nAudioSamples,
543 const AACENC_MetaData * const pMetadata,
544 AACENC_EXT_PAYLOAD ** ppMetaDataExtPayload,
545 UINT * nMetaDataExtensions,
546 INT * matrix_mixdown_idx
547 )
548 {
549 FDK_METADATA_ERROR err = METADATA_OK;
550 int metaDataDelayWriteIdx, metaDataDelayReadIdx, metadataMode;
551
552 /* Where to write new meta data info */
553 metaDataDelayWriteIdx = hMetaDataEnc->metaDataDelayIdx;
554
555 /* How to write the data */
556 metadataMode = hMetaDataEnc->metadataMode;
557
558 /* Compensate meta data delay. */
559 hMetaDataEnc->metaDataDelayIdx++;
560 if (hMetaDataEnc->metaDataDelayIdx > hMetaDataEnc->nMetaDataDelay) hMetaDataEnc->metaDataDelayIdx = 0;
561
562 /* Where to read pending meta data info from. */
563 metaDataDelayReadIdx = hMetaDataEnc->metaDataDelayIdx;
564
565 /* Submit new data if available. */
566 if (pMetadata!=NULL) {
567 FDKmemcpy(&hMetaDataEnc->submittedMetaData, pMetadata, sizeof(AACENC_MetaData));
568 }
569
570 /* Write one additional frame with default configuration of meta data. Ensure defined behaviour on decoder side. */
571 if ( (hMetaDataEnc->finalizeMetaData!=0) && (hMetaDataEnc->metadataMode==0)) {
572 FDKmemcpy(&hMetaDataEnc->submittedMetaData, &defaultMetaDataSetup, sizeof(AACENC_MetaData));
573 metadataMode = hMetaDataEnc->finalizeMetaData;
574 hMetaDataEnc->finalizeMetaData = 0;
575 }
576
577 /* Get last submitted data. */
578 if ( (err = LoadSubmittedMetadata(
579 &hMetaDataEnc->submittedMetaData,
580 hMetaDataEnc->nChannels,
581 metadataMode,
582 &hMetaDataEnc->metaDataBuffer[metaDataDelayWriteIdx])) != METADATA_OK )
583 {
584 goto bail;
585 }
586
587 /* Calculate compressor if necessary and updata meta data info */
588 if (hMetaDataEnc->metaDataBuffer[metaDataDelayWriteIdx].metadataMode != 0) {
589 if ( (err = ProcessCompressor(
590 &hMetaDataEnc->metaDataBuffer[metaDataDelayWriteIdx],
591 hMetaDataEnc->hDrcComp,
592 pAudioSamples,
593 nAudioSamples)) != METADATA_OK)
594 {
595 /* Get last submitted data again. */
596 LoadSubmittedMetadata(
597 &hMetaDataEnc->submittedMetaData,
598 hMetaDataEnc->nChannels,
599 metadataMode,
600 &hMetaDataEnc->metaDataBuffer[metaDataDelayWriteIdx]);
601 }
602 }
603
604 /* Convert Meta Data side info to bitstream data. */
605 if ( (err = WriteMetadataPayload(hMetaDataEnc, &hMetaDataEnc->metaDataBuffer[metaDataDelayReadIdx])) != METADATA_OK ) {
606 goto bail;
607 }
608
609 /* Assign meta data to output */
610 *ppMetaDataExtPayload = hMetaDataEnc->exPayload;
611 *nMetaDataExtensions = hMetaDataEnc->nExtensions;
612 *matrix_mixdown_idx = hMetaDataEnc->matrix_mixdown_idx;
613
614 bail:
615 /* Compensate audio delay, reset err status. */
616 err = CompensateAudioDelay(hMetaDataEnc, pAudioSamples, nAudioSamples);
617
618 return err;
619 }
620
621
CompensateAudioDelay(HANDLE_FDK_METADATA_ENCODER hMetaDataEnc,INT_PCM * const pAudioSamples,const INT nAudioSamples)622 static FDK_METADATA_ERROR CompensateAudioDelay(
623 HANDLE_FDK_METADATA_ENCODER hMetaDataEnc,
624 INT_PCM * const pAudioSamples,
625 const INT nAudioSamples
626 )
627 {
628 FDK_METADATA_ERROR err = METADATA_OK;
629
630 if (hMetaDataEnc->nAudioDataDelay) {
631 int i, delaySamples = hMetaDataEnc->nAudioDataDelay*hMetaDataEnc->nChannels;
632
633 for (i = 0; i < nAudioSamples; i++) {
634 INT_PCM tmp = pAudioSamples[i];
635 pAudioSamples[i] = hMetaDataEnc->audioDelayBuffer[hMetaDataEnc->audioDelayIdx];
636 hMetaDataEnc->audioDelayBuffer[hMetaDataEnc->audioDelayIdx] = tmp;
637
638 hMetaDataEnc->audioDelayIdx++;
639 if (hMetaDataEnc->audioDelayIdx >= delaySamples) hMetaDataEnc->audioDelayIdx = 0;
640 }
641 }
642
643 return err;
644 }
645
646 /*-----------------------------------------------------------------------------
647
648 functionname: WriteMetadataPayload
649 description: fills anc data and extension payload
650 returns: Error status
651
652 ------------------------------------------------------------------------------*/
WriteMetadataPayload(const HANDLE_FDK_METADATA_ENCODER hMetaData,const AAC_METADATA * const pMetadata)653 static FDK_METADATA_ERROR WriteMetadataPayload(
654 const HANDLE_FDK_METADATA_ENCODER hMetaData,
655 const AAC_METADATA * const pMetadata
656 )
657 {
658 FDK_METADATA_ERROR err = METADATA_OK;
659
660 if ( (hMetaData==NULL) || (pMetadata==NULL) ) {
661 err = METADATA_INVALID_HANDLE;
662 goto bail;
663 }
664
665 hMetaData->nExtensions = 0;
666 hMetaData->matrix_mixdown_idx = -1;
667
668 /* AAC-DRC */
669 if (pMetadata->metadataMode != 0)
670 {
671 hMetaData->exPayload[hMetaData->nExtensions].pData = hMetaData->drcInfoPayload;
672 hMetaData->exPayload[hMetaData->nExtensions].dataType = EXT_DYNAMIC_RANGE;
673 hMetaData->exPayload[hMetaData->nExtensions].associatedChElement = -1;
674
675 hMetaData->exPayload[hMetaData->nExtensions].dataSize =
676 WriteDynamicRangeInfoPayload(pMetadata, hMetaData->exPayload[hMetaData->nExtensions].pData);
677
678 hMetaData->nExtensions++;
679
680 /* Matrix Mixdown Coefficient in PCE */
681 if (pMetadata->WritePCEMixDwnIdx) {
682 hMetaData->matrix_mixdown_idx = surmix2matrix_mixdown_idx[pMetadata->surroundMixLevel];
683 }
684
685 /* ETSI TS 101 154 (DVB) - MPEG4 ancillary_data() */
686 if (pMetadata->metadataMode == 2) /* MP4_METADATA_MPEG_ETSI */
687 {
688 hMetaData->exPayload[hMetaData->nExtensions].pData = hMetaData->drcDsePayload;
689 hMetaData->exPayload[hMetaData->nExtensions].dataType = EXT_DATA_ELEMENT;
690 hMetaData->exPayload[hMetaData->nExtensions].associatedChElement = -1;
691
692 hMetaData->exPayload[hMetaData->nExtensions].dataSize =
693 WriteEtsiAncillaryDataPayload(pMetadata,hMetaData->exPayload[hMetaData->nExtensions].pData);
694
695 hMetaData->nExtensions++;
696 } /* metadataMode == 2 */
697
698 } /* metadataMode != 0 */
699
700 bail:
701 return err;
702 }
703
WriteDynamicRangeInfoPayload(const AAC_METADATA * const pMetadata,UCHAR * const pExtensionPayload)704 static INT WriteDynamicRangeInfoPayload(
705 const AAC_METADATA* const pMetadata,
706 UCHAR* const pExtensionPayload
707 )
708 {
709 const INT pce_tag_present = 0; /* yet fixed setting! */
710 const INT prog_ref_lev_res_bits = 0;
711 INT i, drc_num_bands = 1;
712
713 FDK_BITSTREAM bsWriter;
714 FDKinitBitStream(&bsWriter, pExtensionPayload, 16, 0, BS_WRITER);
715
716 /* dynamic_range_info() */
717 FDKwriteBits(&bsWriter, pce_tag_present, 1); /* pce_tag_present */
718 if (pce_tag_present) {
719 FDKwriteBits(&bsWriter, 0x0, 4); /* pce_instance_tag */
720 FDKwriteBits(&bsWriter, 0x0, 4); /* drc_tag_reserved_bits */
721 }
722
723 /* Exclude channels */
724 FDKwriteBits(&bsWriter, (pMetadata->mpegDrc.excluded_chns_present) ? 1 : 0, 1); /* excluded_chns_present*/
725
726 /* Multiband DRC */
727 FDKwriteBits(&bsWriter, (pMetadata->mpegDrc.drc_bands_present) ? 1 : 0, 1); /* drc_bands_present */
728 if (pMetadata->mpegDrc.drc_bands_present)
729 {
730 FDKwriteBits(&bsWriter, pMetadata->mpegDrc.drc_band_incr, 4); /* drc_band_incr */
731 FDKwriteBits(&bsWriter, pMetadata->mpegDrc.drc_interpolation_scheme, 4); /* drc_interpolation_scheme */
732 drc_num_bands += pMetadata->mpegDrc.drc_band_incr;
733 for (i=0; i<drc_num_bands; i++) {
734 FDKwriteBits(&bsWriter, pMetadata->mpegDrc.drc_band_top[i], 8); /* drc_band_top */
735 }
736 }
737
738 /* Program Reference Level */
739 FDKwriteBits(&bsWriter, pMetadata->mpegDrc.prog_ref_level_present, 1); /* prog_ref_level_present */
740 if (pMetadata->mpegDrc.prog_ref_level_present)
741 {
742 FDKwriteBits(&bsWriter, pMetadata->mpegDrc.prog_ref_level, 7); /* prog_ref_level */
743 FDKwriteBits(&bsWriter, prog_ref_lev_res_bits, 1); /* prog_ref_level_reserved_bits */
744 }
745
746 /* DRC Values */
747 for (i=0; i<drc_num_bands; i++) {
748 FDKwriteBits(&bsWriter, (pMetadata->mpegDrc.dyn_rng_sgn[i]) ? 1 : 0, 1); /* dyn_rng_sgn[ */
749 FDKwriteBits(&bsWriter, pMetadata->mpegDrc.dyn_rng_ctl[i], 7); /* dyn_rng_ctl */
750 }
751
752 /* return number of valid bits in extension payload. */
753 return FDKgetValidBits(&bsWriter);
754 }
755
WriteEtsiAncillaryDataPayload(const AAC_METADATA * const pMetadata,UCHAR * const pExtensionPayload)756 static INT WriteEtsiAncillaryDataPayload(
757 const AAC_METADATA* const pMetadata,
758 UCHAR* const pExtensionPayload
759 )
760 {
761 FDK_BITSTREAM bsWriter;
762 FDKinitBitStream(&bsWriter, pExtensionPayload, 16, 0, BS_WRITER);
763
764 /* ancillary_data_sync */
765 FDKwriteBits(&bsWriter, 0xBC, 8);
766
767 /* bs_info */
768 FDKwriteBits(&bsWriter, 0x3, 2); /* mpeg_audio_type */
769 FDKwriteBits(&bsWriter, pMetadata->dolbySurroundMode, 2); /* dolby_surround_mode */
770 FDKwriteBits(&bsWriter, 0x0, 4); /* reserved */
771
772 /* ancillary_data_status */
773 FDKwriteBits(&bsWriter, 0, 3); /* 3 bit Reserved, set to "0" */
774 FDKwriteBits(&bsWriter, (pMetadata->DmxLvl_On) ? 1 : 0, 1); /* downmixing_levels_MPEG4_status */
775 FDKwriteBits(&bsWriter, 0, 1); /* Reserved, set to "0" */
776 FDKwriteBits(&bsWriter, (pMetadata->etsiAncData.compression_on) ? 1 : 0, 1); /* audio_coding_mode_and_compression status */
777 FDKwriteBits(&bsWriter, (pMetadata->etsiAncData.timecode_coarse_status) ? 1 : 0, 1); /* coarse_grain_timecode_status */
778 FDKwriteBits(&bsWriter, (pMetadata->etsiAncData.timecode_fine_status) ? 1 : 0, 1); /* fine_grain_timecode_status */
779
780 /* downmixing_levels_MPEG4_status */
781 if (pMetadata->DmxLvl_On) {
782 FDKwriteBits(&bsWriter, encodeDmxLvls(pMetadata->centerMixLevel, pMetadata->surroundMixLevel), 8);
783 }
784
785 /* audio_coding_mode_and_compression_status */
786 if (pMetadata->etsiAncData.compression_on) {
787 FDKwriteBits(&bsWriter, 0x01, 8); /* audio coding mode */
788 FDKwriteBits(&bsWriter, pMetadata->etsiAncData.compression_value, 8); /* compression value */
789 }
790
791 /* grain-timecode coarse/fine */
792 if (pMetadata->etsiAncData.timecode_coarse_status) {
793 FDKwriteBits(&bsWriter, 0x0, 16); /* not yet supported */
794 }
795
796 if (pMetadata->etsiAncData.timecode_fine_status) {
797 FDKwriteBits(&bsWriter, 0x0, 16); /* not yet supported */
798 }
799
800 return FDKgetValidBits(&bsWriter);
801 }
802
803
LoadSubmittedMetadata(const AACENC_MetaData * const hMetadata,const INT nChannels,const INT metadataMode,AAC_METADATA * const pAacMetaData)804 static FDK_METADATA_ERROR LoadSubmittedMetadata(
805 const AACENC_MetaData * const hMetadata,
806 const INT nChannels,
807 const INT metadataMode,
808 AAC_METADATA * const pAacMetaData
809 )
810 {
811 FDK_METADATA_ERROR err = METADATA_OK;
812
813 if (pAacMetaData==NULL) {
814 err = METADATA_INVALID_HANDLE;
815 }
816 else {
817 /* init struct */
818 FDKmemclear(pAacMetaData, sizeof(AAC_METADATA));
819
820 if (hMetadata!=NULL) {
821 /* convert data */
822 pAacMetaData->mpegDrc.drc_profile = hMetadata->drc_profile;
823 pAacMetaData->etsiAncData.comp_profile = hMetadata->comp_profile;
824 pAacMetaData->mpegDrc.drc_TargetRefLevel = hMetadata->drc_TargetRefLevel;
825 pAacMetaData->etsiAncData.comp_TargetRefLevel= hMetadata->comp_TargetRefLevel;
826 pAacMetaData->mpegDrc.prog_ref_level_present = hMetadata->prog_ref_level_present;
827 pAacMetaData->mpegDrc.prog_ref_level = dialnorm2progreflvl(hMetadata->prog_ref_level);
828
829 pAacMetaData->centerMixLevel = hMetadata->centerMixLevel;
830 pAacMetaData->surroundMixLevel = hMetadata->surroundMixLevel;
831 pAacMetaData->WritePCEMixDwnIdx = hMetadata->PCE_mixdown_idx_present;
832 pAacMetaData->DmxLvl_On = hMetadata->ETSI_DmxLvl_present;
833
834 pAacMetaData->etsiAncData.compression_on = 1;
835
836
837 if (nChannels == 2) {
838 pAacMetaData->dolbySurroundMode = hMetadata->dolbySurroundMode; /* dolby_surround_mode */
839 } else {
840 pAacMetaData->dolbySurroundMode = 0;
841 }
842
843 pAacMetaData->etsiAncData.timecode_coarse_status = 0; /* not yet supported - attention: Update GetEstMetadataBytesPerFrame() if enable this! */
844 pAacMetaData->etsiAncData.timecode_fine_status = 0; /* not yet supported - attention: Update GetEstMetadataBytesPerFrame() if enable this! */
845
846 pAacMetaData->metadataMode = metadataMode;
847 }
848 else {
849 pAacMetaData->metadataMode = 0; /* there is no configuration available */
850 }
851 }
852
853 return err;
854 }
855
FDK_MetadataEnc_GetDelay(HANDLE_FDK_METADATA_ENCODER hMetadataEnc)856 INT FDK_MetadataEnc_GetDelay(
857 HANDLE_FDK_METADATA_ENCODER hMetadataEnc
858 )
859 {
860 INT delay = 0;
861
862 if (hMetadataEnc!=NULL) {
863 delay = hMetadataEnc->nAudioDataDelay;
864 }
865
866 return delay;
867 }
868
869
870