1 2/* ----------------------------------------------------------------------------------------------------------- 3Software 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 9The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements 10the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. 11This FDK AAC Codec software is intended to be used on a wide variety of Android devices. 12 13AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual 14audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by 15independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part 16of the MPEG specifications. 17 18Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) 19may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners 20individually for the purpose of encoding or decoding bit streams in products that are compliant with 21the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license 22these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec 23software may already be covered under those patent licenses when it is used for those licensed purposes only. 24 25Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, 26are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional 27applications information and documentation. 28 292. COPYRIGHT LICENSE 30 31Redistribution and use in source and binary forms, with or without modification, are permitted without 32payment of copyright license fees provided that you satisfy the following conditions: 33 34You must retain the complete text of this software license in redistributions of the FDK AAC Codec or 35your modifications thereto in source code form. 36 37You must retain the complete text of this software license in the documentation and/or other materials 38provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. 39You must make available free of charge copies of the complete source code of the FDK AAC Codec and your 40modifications thereto to recipients of copies in binary form. 41 42The name of Fraunhofer may not be used to endorse or promote products derived from this library without 43prior written permission. 44 45You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec 46software or your modifications thereto. 47 48Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software 49and 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 533. NO PATENT LICENSE 54 55NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, 56ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with 57respect to this software. 58 59You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized 60by appropriate patent licenses. 61 624. DISCLAIMER 63 64This 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 66of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 67CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, 68including but not limited to procurement of substitute goods or services; loss of use, data, or profits, 69or business interruption, however caused and on any theory of liability, whether in contract, strict 70liability, or tort (including negligence), arising in any way out of the use of this software, even if 71advised of the possibility of such damage. 72 735. CONTACT INFORMATION 74 75Fraunhofer Institute for Integrated Circuits IIS 76Attention: Audio and Multimedia Departments - FDK AAC LL 77Am Wolfsmantel 33 7891058 Erlangen, Germany 79 80www.iis.fraunhofer.de/amm 81amm-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 105typedef 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 149struct 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 -----------------------*/ 178static 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 192static 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 197static const UCHAR surmix2matrix_mixdown_idx[8] = { 198 0, 0, 0, 1, 1, 2, 2, 3 199}; 200 201 202/*--------------- function declarations --------------------*/ 203static FDK_METADATA_ERROR WriteMetadataPayload( 204 const HANDLE_FDK_METADATA_ENCODER hMetaData, 205 const AAC_METADATA * const pMetadata 206 ); 207 208static INT WriteDynamicRangeInfoPayload( 209 const AAC_METADATA* const pMetadata, 210 UCHAR* const pExtensionPayload 211 ); 212 213static INT WriteEtsiAncillaryDataPayload( 214 const AAC_METADATA* const pMetadata, 215 UCHAR* const pExtensionPayload 216 ); 217 218static FDK_METADATA_ERROR CompensateAudioDelay( 219 HANDLE_FDK_METADATA_ENCODER hMetaDataEnc, 220 INT_PCM * const pAudioSamples, 221 const INT nAudioSamples 222 ); 223 224static 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 231static 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 240static 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 */ 259static 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 */ 265static INT progreflvl2dialnorm(const UCHAR p) 266{ 267 return -((INT)(p<<(16-2))); 268} 269 270/* encode downmix levels to Downmixing_levels_MPEG4 */ 271static 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) */ 281static 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) */ 298static 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) */ 307static 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) */ 330static 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 343FDK_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 376bail: 377 FDK_MetadataEnc_Close(&hMetaData); 378 return err; 379} 380 381FDK_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 } 397bail: 398 return err; 399} 400 401FDK_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 } 478bail: 479 return err; 480} 481 482static 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 535bail: 536 return err; 537} 538 539FDK_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 614bail: 615 /* Compensate audio delay, reset err status. */ 616 err = CompensateAudioDelay(hMetaDataEnc, pAudioSamples, nAudioSamples); 617 618 return err; 619} 620 621 622static 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 ------------------------------------------------------------------------------*/ 653static 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 700bail: 701 return err; 702} 703 704static 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 756static 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 804static 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 856INT 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