Imported Debian version 0.1.3.1
[deb_fdk-aac.git] / libAACenc / src / metadata_main.cpp
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
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 */
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 */
265 static INT progreflvl2dialnorm(const UCHAR p)
266 {
267 return -((INT)(p<<(16-2)));
268 }
269
270 /* encode downmix levels to Downmixing_levels_MPEG4 */
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) */
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) */
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) */
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) */
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
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
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
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
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 INT dynrng, compr;
492 DRC_PROFILE profileDrc = convertProfile(pMetadata->mpegDrc.drc_profile);
493 DRC_PROFILE profileComp = convertProfile(pMetadata->etsiAncData.comp_profile);
494
495 if ( (pMetadata==NULL) || (hDrcComp==NULL) ) {
496 err = METADATA_INVALID_HANDLE;
497 return err;
498 }
499
500 /* first, check if profile is same as last frame
501 * otherwise, update setup */
502 if ( (profileDrc != FDK_DRC_Generator_getDrcProfile(hDrcComp))
503 || (profileComp != FDK_DRC_Generator_getCompProfile(hDrcComp)) )
504 {
505 FDK_DRC_Generator_setDrcProfile(hDrcComp, profileDrc, profileComp);
506 }
507
508 /* Sanity check */
509 if (profileComp == DRC_NONE) {
510 pMetadata->etsiAncData.compression_value = 0x80; /* to ensure no external values will be written if not configured */
511 }
512
513 /* in case of embedding external values, copy this now (limiter may overwrite them) */
514 dynrng = decodeDynrng(pMetadata->mpegDrc.dyn_rng_ctl[0], pMetadata->mpegDrc.dyn_rng_sgn[0]);
515 compr = decodeCompr(pMetadata->etsiAncData.compression_value);
516
517 /* Call compressor */
518 if (FDK_DRC_Generator_Calc(hDrcComp,
519 pSamples,
520 progreflvl2dialnorm(pMetadata->mpegDrc.prog_ref_level),
521 pMetadata->mpegDrc.drc_TargetRefLevel,
522 pMetadata->etsiAncData.comp_TargetRefLevel,
523 dmxTable[pMetadata->centerMixLevel],
524 dmxTable[pMetadata->surroundMixLevel],
525 &dynrng,
526 &compr) != 0)
527 {
528 err = METADATA_ENCODE_ERROR;
529 goto bail;
530 }
531
532 /* Write DRC values */
533 pMetadata->mpegDrc.drc_band_incr = 0;
534 encodeDynrng(dynrng, pMetadata->mpegDrc.dyn_rng_ctl, pMetadata->mpegDrc.dyn_rng_sgn);
535 pMetadata->etsiAncData.compression_value = encodeCompr(compr);
536
537 bail:
538 return err;
539 }
540
541 FDK_METADATA_ERROR FDK_MetadataEnc_Process(
542 HANDLE_FDK_METADATA_ENCODER hMetaDataEnc,
543 INT_PCM * const pAudioSamples,
544 const INT nAudioSamples,
545 const AACENC_MetaData * const pMetadata,
546 AACENC_EXT_PAYLOAD ** ppMetaDataExtPayload,
547 UINT * nMetaDataExtensions,
548 INT * matrix_mixdown_idx
549 )
550 {
551 FDK_METADATA_ERROR err = METADATA_OK;
552 int metaDataDelayWriteIdx, metaDataDelayReadIdx, metadataMode;
553
554 /* Where to write new meta data info */
555 metaDataDelayWriteIdx = hMetaDataEnc->metaDataDelayIdx;
556
557 /* How to write the data */
558 metadataMode = hMetaDataEnc->metadataMode;
559
560 /* Compensate meta data delay. */
561 hMetaDataEnc->metaDataDelayIdx++;
562 if (hMetaDataEnc->metaDataDelayIdx > hMetaDataEnc->nMetaDataDelay) hMetaDataEnc->metaDataDelayIdx = 0;
563
564 /* Where to read pending meta data info from. */
565 metaDataDelayReadIdx = hMetaDataEnc->metaDataDelayIdx;
566
567 /* Submit new data if available. */
568 if (pMetadata!=NULL) {
569 FDKmemcpy(&hMetaDataEnc->submittedMetaData, pMetadata, sizeof(AACENC_MetaData));
570 }
571
572 /* Write one additional frame with default configuration of meta data. Ensure defined behaviour on decoder side. */
573 if ( (hMetaDataEnc->finalizeMetaData!=0) && (hMetaDataEnc->metadataMode==0)) {
574 FDKmemcpy(&hMetaDataEnc->submittedMetaData, &defaultMetaDataSetup, sizeof(AACENC_MetaData));
575 metadataMode = hMetaDataEnc->finalizeMetaData;
576 hMetaDataEnc->finalizeMetaData = 0;
577 }
578
579 /* Get last submitted data. */
580 if ( (err = LoadSubmittedMetadata(
581 &hMetaDataEnc->submittedMetaData,
582 hMetaDataEnc->nChannels,
583 metadataMode,
584 &hMetaDataEnc->metaDataBuffer[metaDataDelayWriteIdx])) != METADATA_OK )
585 {
586 goto bail;
587 }
588
589 /* Calculate compressor if necessary and updata meta data info */
590 if (hMetaDataEnc->metaDataBuffer[metaDataDelayWriteIdx].metadataMode != 0) {
591 if ( (err = ProcessCompressor(
592 &hMetaDataEnc->metaDataBuffer[metaDataDelayWriteIdx],
593 hMetaDataEnc->hDrcComp,
594 pAudioSamples,
595 nAudioSamples)) != METADATA_OK)
596 {
597 /* Get last submitted data again. */
598 LoadSubmittedMetadata(
599 &hMetaDataEnc->submittedMetaData,
600 hMetaDataEnc->nChannels,
601 metadataMode,
602 &hMetaDataEnc->metaDataBuffer[metaDataDelayWriteIdx]);
603 }
604 }
605
606 /* Convert Meta Data side info to bitstream data. */
607 if ( (err = WriteMetadataPayload(hMetaDataEnc, &hMetaDataEnc->metaDataBuffer[metaDataDelayReadIdx])) != METADATA_OK ) {
608 goto bail;
609 }
610
611 /* Assign meta data to output */
612 *ppMetaDataExtPayload = hMetaDataEnc->exPayload;
613 *nMetaDataExtensions = hMetaDataEnc->nExtensions;
614 *matrix_mixdown_idx = hMetaDataEnc->matrix_mixdown_idx;
615
616 bail:
617 /* Compensate audio delay, reset err status. */
618 err = CompensateAudioDelay(hMetaDataEnc, pAudioSamples, nAudioSamples);
619
620 return err;
621 }
622
623
624 static FDK_METADATA_ERROR CompensateAudioDelay(
625 HANDLE_FDK_METADATA_ENCODER hMetaDataEnc,
626 INT_PCM * const pAudioSamples,
627 const INT nAudioSamples
628 )
629 {
630 FDK_METADATA_ERROR err = METADATA_OK;
631
632 if (hMetaDataEnc->nAudioDataDelay) {
633 int i, delaySamples = hMetaDataEnc->nAudioDataDelay*hMetaDataEnc->nChannels;
634
635 for (i = 0; i < nAudioSamples; i++) {
636 INT_PCM tmp = pAudioSamples[i];
637 pAudioSamples[i] = hMetaDataEnc->audioDelayBuffer[hMetaDataEnc->audioDelayIdx];
638 hMetaDataEnc->audioDelayBuffer[hMetaDataEnc->audioDelayIdx] = tmp;
639
640 hMetaDataEnc->audioDelayIdx++;
641 if (hMetaDataEnc->audioDelayIdx >= delaySamples) hMetaDataEnc->audioDelayIdx = 0;
642 }
643 }
644
645 return err;
646 }
647
648 /*-----------------------------------------------------------------------------
649
650 functionname: WriteMetadataPayload
651 description: fills anc data and extension payload
652 returns: Error status
653
654 ------------------------------------------------------------------------------*/
655 static FDK_METADATA_ERROR WriteMetadataPayload(
656 const HANDLE_FDK_METADATA_ENCODER hMetaData,
657 const AAC_METADATA * const pMetadata
658 )
659 {
660 FDK_METADATA_ERROR err = METADATA_OK;
661
662 if ( (hMetaData==NULL) || (pMetadata==NULL) ) {
663 err = METADATA_INVALID_HANDLE;
664 goto bail;
665 }
666
667 hMetaData->nExtensions = 0;
668 hMetaData->matrix_mixdown_idx = -1;
669
670 /* AAC-DRC */
671 if (pMetadata->metadataMode != 0)
672 {
673 hMetaData->exPayload[hMetaData->nExtensions].pData = hMetaData->drcInfoPayload;
674 hMetaData->exPayload[hMetaData->nExtensions].dataType = EXT_DYNAMIC_RANGE;
675 hMetaData->exPayload[hMetaData->nExtensions].associatedChElement = -1;
676
677 hMetaData->exPayload[hMetaData->nExtensions].dataSize =
678 WriteDynamicRangeInfoPayload(pMetadata, hMetaData->exPayload[hMetaData->nExtensions].pData);
679
680 hMetaData->nExtensions++;
681
682 /* Matrix Mixdown Coefficient in PCE */
683 if (pMetadata->WritePCEMixDwnIdx) {
684 hMetaData->matrix_mixdown_idx = surmix2matrix_mixdown_idx[pMetadata->surroundMixLevel];
685 }
686
687 /* ETSI TS 101 154 (DVB) - MPEG4 ancillary_data() */
688 if (pMetadata->metadataMode == 2) /* MP4_METADATA_MPEG_ETSI */
689 {
690 hMetaData->exPayload[hMetaData->nExtensions].pData = hMetaData->drcDsePayload;
691 hMetaData->exPayload[hMetaData->nExtensions].dataType = EXT_DATA_ELEMENT;
692 hMetaData->exPayload[hMetaData->nExtensions].associatedChElement = -1;
693
694 hMetaData->exPayload[hMetaData->nExtensions].dataSize =
695 WriteEtsiAncillaryDataPayload(pMetadata,hMetaData->exPayload[hMetaData->nExtensions].pData);
696
697 hMetaData->nExtensions++;
698 } /* metadataMode == 2 */
699
700 } /* metadataMode != 0 */
701
702 bail:
703 return err;
704 }
705
706 static INT WriteDynamicRangeInfoPayload(
707 const AAC_METADATA* const pMetadata,
708 UCHAR* const pExtensionPayload
709 )
710 {
711 const INT pce_tag_present = 0; /* yet fixed setting! */
712 const INT prog_ref_lev_res_bits = 0;
713 INT i, drc_num_bands = 1;
714
715 FDK_BITSTREAM bsWriter;
716 FDKinitBitStream(&bsWriter, pExtensionPayload, 16, 0, BS_WRITER);
717
718 /* dynamic_range_info() */
719 FDKwriteBits(&bsWriter, pce_tag_present, 1); /* pce_tag_present */
720 if (pce_tag_present) {
721 FDKwriteBits(&bsWriter, 0x0, 4); /* pce_instance_tag */
722 FDKwriteBits(&bsWriter, 0x0, 4); /* drc_tag_reserved_bits */
723 }
724
725 /* Exclude channels */
726 FDKwriteBits(&bsWriter, (pMetadata->mpegDrc.excluded_chns_present) ? 1 : 0, 1); /* excluded_chns_present*/
727
728 /* Multiband DRC */
729 FDKwriteBits(&bsWriter, (pMetadata->mpegDrc.drc_bands_present) ? 1 : 0, 1); /* drc_bands_present */
730 if (pMetadata->mpegDrc.drc_bands_present)
731 {
732 FDKwriteBits(&bsWriter, pMetadata->mpegDrc.drc_band_incr, 4); /* drc_band_incr */
733 FDKwriteBits(&bsWriter, pMetadata->mpegDrc.drc_interpolation_scheme, 4); /* drc_interpolation_scheme */
734 drc_num_bands += pMetadata->mpegDrc.drc_band_incr;
735 for (i=0; i<drc_num_bands; i++) {
736 FDKwriteBits(&bsWriter, pMetadata->mpegDrc.drc_band_top[i], 8); /* drc_band_top */
737 }
738 }
739
740 /* Program Reference Level */
741 FDKwriteBits(&bsWriter, pMetadata->mpegDrc.prog_ref_level_present, 1); /* prog_ref_level_present */
742 if (pMetadata->mpegDrc.prog_ref_level_present)
743 {
744 FDKwriteBits(&bsWriter, pMetadata->mpegDrc.prog_ref_level, 7); /* prog_ref_level */
745 FDKwriteBits(&bsWriter, prog_ref_lev_res_bits, 1); /* prog_ref_level_reserved_bits */
746 }
747
748 /* DRC Values */
749 for (i=0; i<drc_num_bands; i++) {
750 FDKwriteBits(&bsWriter, (pMetadata->mpegDrc.dyn_rng_sgn[i]) ? 1 : 0, 1); /* dyn_rng_sgn[ */
751 FDKwriteBits(&bsWriter, pMetadata->mpegDrc.dyn_rng_ctl[i], 7); /* dyn_rng_ctl */
752 }
753
754 /* return number of valid bits in extension payload. */
755 return FDKgetValidBits(&bsWriter);
756 }
757
758 static INT WriteEtsiAncillaryDataPayload(
759 const AAC_METADATA* const pMetadata,
760 UCHAR* const pExtensionPayload
761 )
762 {
763 FDK_BITSTREAM bsWriter;
764 FDKinitBitStream(&bsWriter, pExtensionPayload, 16, 0, BS_WRITER);
765
766 /* ancillary_data_sync */
767 FDKwriteBits(&bsWriter, 0xBC, 8);
768
769 /* bs_info */
770 FDKwriteBits(&bsWriter, 0x3, 2); /* mpeg_audio_type */
771 FDKwriteBits(&bsWriter, pMetadata->dolbySurroundMode, 2); /* dolby_surround_mode */
772 FDKwriteBits(&bsWriter, 0x0, 4); /* reserved */
773
774 /* ancillary_data_status */
775 FDKwriteBits(&bsWriter, 0, 3); /* 3 bit Reserved, set to "0" */
776 FDKwriteBits(&bsWriter, (pMetadata->DmxLvl_On) ? 1 : 0, 1); /* downmixing_levels_MPEG4_status */
777 FDKwriteBits(&bsWriter, 0, 1); /* Reserved, set to "0" */
778 FDKwriteBits(&bsWriter, (pMetadata->etsiAncData.compression_on) ? 1 : 0, 1); /* audio_coding_mode_and_compression status */
779 FDKwriteBits(&bsWriter, (pMetadata->etsiAncData.timecode_coarse_status) ? 1 : 0, 1); /* coarse_grain_timecode_status */
780 FDKwriteBits(&bsWriter, (pMetadata->etsiAncData.timecode_fine_status) ? 1 : 0, 1); /* fine_grain_timecode_status */
781
782 /* downmixing_levels_MPEG4_status */
783 if (pMetadata->DmxLvl_On) {
784 FDKwriteBits(&bsWriter, encodeDmxLvls(pMetadata->centerMixLevel, pMetadata->surroundMixLevel), 8);
785 }
786
787 /* audio_coding_mode_and_compression_status */
788 if (pMetadata->etsiAncData.compression_on) {
789 FDKwriteBits(&bsWriter, 0x01, 8); /* audio coding mode */
790 FDKwriteBits(&bsWriter, pMetadata->etsiAncData.compression_value, 8); /* compression value */
791 }
792
793 /* grain-timecode coarse/fine */
794 if (pMetadata->etsiAncData.timecode_coarse_status) {
795 FDKwriteBits(&bsWriter, 0x0, 16); /* not yet supported */
796 }
797
798 if (pMetadata->etsiAncData.timecode_fine_status) {
799 FDKwriteBits(&bsWriter, 0x0, 16); /* not yet supported */
800 }
801
802 return FDKgetValidBits(&bsWriter);
803 }
804
805
806 static FDK_METADATA_ERROR LoadSubmittedMetadata(
807 const AACENC_MetaData * const hMetadata,
808 const INT nChannels,
809 const INT metadataMode,
810 AAC_METADATA * const pAacMetaData
811 )
812 {
813 FDK_METADATA_ERROR err = METADATA_OK;
814
815 if (pAacMetaData==NULL) {
816 err = METADATA_INVALID_HANDLE;
817 }
818 else {
819 /* init struct */
820 FDKmemclear(pAacMetaData, sizeof(AAC_METADATA));
821
822 if (hMetadata!=NULL) {
823 /* convert data */
824 pAacMetaData->mpegDrc.drc_profile = hMetadata->drc_profile;
825 pAacMetaData->etsiAncData.comp_profile = hMetadata->comp_profile;
826 pAacMetaData->mpegDrc.drc_TargetRefLevel = hMetadata->drc_TargetRefLevel;
827 pAacMetaData->etsiAncData.comp_TargetRefLevel= hMetadata->comp_TargetRefLevel;
828 pAacMetaData->mpegDrc.prog_ref_level_present = hMetadata->prog_ref_level_present;
829 pAacMetaData->mpegDrc.prog_ref_level = dialnorm2progreflvl(hMetadata->prog_ref_level);
830
831 pAacMetaData->centerMixLevel = hMetadata->centerMixLevel;
832 pAacMetaData->surroundMixLevel = hMetadata->surroundMixLevel;
833 pAacMetaData->WritePCEMixDwnIdx = hMetadata->PCE_mixdown_idx_present;
834 pAacMetaData->DmxLvl_On = hMetadata->ETSI_DmxLvl_present;
835
836 pAacMetaData->etsiAncData.compression_on = 1;
837
838
839 if (nChannels == 2) {
840 pAacMetaData->dolbySurroundMode = hMetadata->dolbySurroundMode; /* dolby_surround_mode */
841 } else {
842 pAacMetaData->dolbySurroundMode = 0;
843 }
844
845 pAacMetaData->etsiAncData.timecode_coarse_status = 0; /* not yet supported - attention: Update GetEstMetadataBytesPerFrame() if enable this! */
846 pAacMetaData->etsiAncData.timecode_fine_status = 0; /* not yet supported - attention: Update GetEstMetadataBytesPerFrame() if enable this! */
847
848 pAacMetaData->metadataMode = metadataMode;
849 }
850 else {
851 pAacMetaData->metadataMode = 0; /* there is no configuration available */
852 }
853 }
854
855 return err;
856 }
857
858 INT FDK_MetadataEnc_GetDelay(
859 HANDLE_FDK_METADATA_ENCODER hMetadataEnc
860 )
861 {
862 INT delay = 0;
863
864 if (hMetadataEnc!=NULL) {
865 delay = hMetadataEnc->nAudioDataDelay;
866 }
867
868 return delay;
869 }
870
871