• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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