| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869 |
- /* -----------------------------------------------------------------------------------------------------------
- Software License for The Fraunhofer FDK AAC Codec Library for Android
- © Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
- All rights reserved.
- 1. INTRODUCTION
- The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements
- the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio.
- This FDK AAC Codec software is intended to be used on a wide variety of Android devices.
- AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual
- audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by
- independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part
- of the MPEG specifications.
- Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer)
- may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners
- individually for the purpose of encoding or decoding bit streams in products that are compliant with
- the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license
- these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec
- software may already be covered under those patent licenses when it is used for those licensed purposes only.
- Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality,
- are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional
- applications information and documentation.
- 2. COPYRIGHT LICENSE
- Redistribution and use in source and binary forms, with or without modification, are permitted without
- payment of copyright license fees provided that you satisfy the following conditions:
- You must retain the complete text of this software license in redistributions of the FDK AAC Codec or
- your modifications thereto in source code form.
- You must retain the complete text of this software license in the documentation and/or other materials
- provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form.
- You must make available free of charge copies of the complete source code of the FDK AAC Codec and your
- modifications thereto to recipients of copies in binary form.
- The name of Fraunhofer may not be used to endorse or promote products derived from this library without
- prior written permission.
- You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec
- software or your modifications thereto.
- Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software
- and the date of any change. For modified versions of the FDK AAC Codec, the term
- "Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term
- "Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android."
- 3. NO PATENT LICENSE
- NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer,
- ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with
- respect to this software.
- You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized
- by appropriate patent licenses.
- 4. DISCLAIMER
- This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors
- "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties
- of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
- CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages,
- including but not limited to procurement of substitute goods or services; loss of use, data, or profits,
- or business interruption, however caused and on any theory of liability, whether in contract, strict
- liability, or tort (including negligence), arising in any way out of the use of this software, even if
- advised of the possibility of such damage.
- 5. CONTACT INFORMATION
- Fraunhofer Institute for Integrated Circuits IIS
- Attention: Audio and Multimedia Departments - FDK AAC LL
- Am Wolfsmantel 33
- 91058 Erlangen, Germany
- www.iis.fraunhofer.de/amm
- [email protected]
- ----------------------------------------------------------------------------------------------------------- */
- /********************** Fraunhofer IIS FDK AAC Encoder lib ******************
- Author(s): V. Bacigalupo
- Description: Metadata Encoder library interface functions
- ******************************************************************************/
- #include "metadata_main.h"
- #include "metadata_compressor.h"
- #include "FDK_bitstream.h"
- #include "FDK_audio.h"
- #include "genericStds.h"
- /*----------------- defines ----------------------*/
- #define MAX_DRC_BANDS (1<<4)
- #define MAX_DRC_CHANNELS (8)
- #define MAX_DRC_FRAMELEN (2*1024)
- /*--------------- structure definitions --------------------*/
- typedef struct AAC_METADATA
- {
- /* MPEG: Dynamic Range Control */
- struct {
- UCHAR prog_ref_level_present;
- SCHAR prog_ref_level;
- UCHAR dyn_rng_sgn[MAX_DRC_BANDS];
- UCHAR dyn_rng_ctl[MAX_DRC_BANDS];
- UCHAR drc_bands_present;
- UCHAR drc_band_incr;
- UCHAR drc_band_top[MAX_DRC_BANDS];
- UCHAR drc_interpolation_scheme;
- AACENC_METADATA_DRC_PROFILE drc_profile;
- INT drc_TargetRefLevel; /* used for Limiter */
- /* excluded channels */
- UCHAR excluded_chns_present;
- UCHAR exclude_mask[2]; /* MAX_NUMBER_CHANNELS/8 */
- } mpegDrc;
- /* ETSI: addtl ancillary data */
- struct {
- /* Heavy Compression */
- UCHAR compression_on; /* flag, if compression value should be written */
- UCHAR compression_value; /* compression value */
- AACENC_METADATA_DRC_PROFILE comp_profile;
- INT comp_TargetRefLevel; /* used for Limiter */
- INT timecode_coarse_status;
- INT timecode_fine_status;
- } etsiAncData;
- SCHAR centerMixLevel; /* center downmix level (0...7, according to table) */
- SCHAR surroundMixLevel; /* surround downmix level (0...7, according to table) */
- UCHAR WritePCEMixDwnIdx; /* flag */
- UCHAR DmxLvl_On; /* flag */
- UCHAR dolbySurroundMode;
- UCHAR metadataMode; /* indicate meta data mode in current frame (delay line) */
- } AAC_METADATA;
- struct FDK_METADATA_ENCODER
- {
- INT metadataMode;
- HDRC_COMP hDrcComp;
- AACENC_MetaData submittedMetaData;
- INT nAudioDataDelay;
- INT nMetaDataDelay;
- INT nChannels;
- INT_PCM audioDelayBuffer[MAX_DRC_CHANNELS*MAX_DRC_FRAMELEN];
- int audioDelayIdx;
- AAC_METADATA metaDataBuffer[3];
- int metaDataDelayIdx;
- UCHAR drcInfoPayload[12];
- UCHAR drcDsePayload[8];
- INT matrix_mixdown_idx;
- AACENC_EXT_PAYLOAD exPayload[2];
- INT nExtensions;
- INT finalizeMetaData; /* Delay switch off by one frame and write default configuration to
- finalize the metadata setup. */
- };
- /*---------------- constants -----------------------*/
- static const AACENC_MetaData defaultMetaDataSetup = {
- AACENC_METADATA_DRC_NONE,
- AACENC_METADATA_DRC_NONE,
- -(31<<16),
- -(31<<16),
- 0,
- -(31<<16),
- 0,
- 0,
- 0,
- 0,
- 0
- };
- static const FIXP_DBL dmxTable[8] = {
- ((FIXP_DBL)MAXVAL_DBL), FL2FXCONST_DBL(0.841f), FL2FXCONST_DBL(0.707f), FL2FXCONST_DBL(0.596f),
- FL2FXCONST_DBL(0.500f), FL2FXCONST_DBL(0.422f), FL2FXCONST_DBL(0.355f), FL2FXCONST_DBL(0.000f)
- };
- static const UCHAR surmix2matrix_mixdown_idx[8] = {
- 0, 0, 0, 1, 1, 2, 2, 3
- };
- /*--------------- function declarations --------------------*/
- static FDK_METADATA_ERROR WriteMetadataPayload(
- const HANDLE_FDK_METADATA_ENCODER hMetaData,
- const AAC_METADATA * const pMetadata
- );
- static INT WriteDynamicRangeInfoPayload(
- const AAC_METADATA* const pMetadata,
- UCHAR* const pExtensionPayload
- );
- static INT WriteEtsiAncillaryDataPayload(
- const AAC_METADATA* const pMetadata,
- UCHAR* const pExtensionPayload
- );
- static FDK_METADATA_ERROR CompensateAudioDelay(
- HANDLE_FDK_METADATA_ENCODER hMetaDataEnc,
- INT_PCM * const pAudioSamples,
- const INT nAudioSamples
- );
- static FDK_METADATA_ERROR LoadSubmittedMetadata(
- const AACENC_MetaData * const hMetadata,
- const INT nChannels,
- const INT metadataMode,
- AAC_METADATA * const pAacMetaData
- );
- static FDK_METADATA_ERROR ProcessCompressor(
- AAC_METADATA *pMetadata,
- HDRC_COMP hDrcComp,
- const INT_PCM * const pSamples,
- const INT nSamples
- );
- /*------------- function definitions ----------------*/
- static DRC_PROFILE convertProfile(AACENC_METADATA_DRC_PROFILE aacProfile)
- {
- DRC_PROFILE drcProfile = DRC_NONE;
- switch(aacProfile) {
- case AACENC_METADATA_DRC_NONE: drcProfile = DRC_NONE; break;
- case AACENC_METADATA_DRC_FILMSTANDARD: drcProfile = DRC_FILMSTANDARD; break;
- case AACENC_METADATA_DRC_FILMLIGHT: drcProfile = DRC_FILMLIGHT; break;
- case AACENC_METADATA_DRC_MUSICSTANDARD: drcProfile = DRC_MUSICSTANDARD; break;
- case AACENC_METADATA_DRC_MUSICLIGHT: drcProfile = DRC_MUSICLIGHT; break;
- case AACENC_METADATA_DRC_SPEECH: drcProfile = DRC_SPEECH; break;
- default: drcProfile = DRC_NONE; break;
- }
- return drcProfile;
- }
- /* convert dialog normalization to program reference level */
- /* NOTE: this only is correct, if the decoder target level is set to -31dB for line mode / -20dB for RF mode */
- static UCHAR dialnorm2progreflvl(const INT d)
- {
- return ((UCHAR)FDKmax(0, FDKmin((-d + (1<<13)) >> 14, 127)));
- }
- /* convert program reference level to dialog normalization */
- static INT progreflvl2dialnorm(const UCHAR p)
- {
- return -((INT)(p<<(16-2)));
- }
- /* encode downmix levels to Downmixing_levels_MPEG4 */
- static SCHAR encodeDmxLvls(const SCHAR cmixlev, const SCHAR surmixlev)
- {
- SCHAR dmxLvls = 0;
- dmxLvls |= 0x80 | (cmixlev << 4); /* center_mix_level_on */
- dmxLvls |= 0x08 | surmixlev; /* surround_mix_level_on */
- return dmxLvls;
- }
- /* encode AAC DRC gain (ISO/IEC 14496-3:2005 4.5.2.7) */
- static void encodeDynrng(INT gain, UCHAR* const dyn_rng_ctl, UCHAR* const dyn_rng_sgn )
- {
- if(gain < 0)
- {
- *dyn_rng_sgn = 1;
- gain = -gain;
- }
- else
- {
- *dyn_rng_sgn = 0;
- }
- gain = FDKmin(gain,(127<<14));
- *dyn_rng_ctl = (UCHAR)((gain + (1<<13)) >> 14);
- }
- /* decode AAC DRC gain (ISO/IEC 14496-3:2005 4.5.2.7) */
- static INT decodeDynrng(const UCHAR dyn_rng_ctl, const UCHAR dyn_rng_sgn)
- {
- INT tmp = ((INT)dyn_rng_ctl << (16-2));
- if (dyn_rng_sgn) tmp = -tmp;
- return tmp;
- }
- /* encode AAC compression value (ETSI TS 101 154 page 99) */
- static UCHAR encodeCompr(INT gain)
- {
- UCHAR x, y;
- INT tmp;
- /* tmp = (int)((48.164f - gain) / 6.0206f * 15 + 0.5f); */
- tmp = ((3156476 - gain) * 15 + 197283) / 394566;
- if (tmp >= 240) {
- return 0xFF;
- }
- else if (tmp < 0) {
- return 0;
- }
- else {
- x = tmp / 15;
- y = tmp % 15;
- }
- return (x << 4) | y;
- }
- /* decode AAC compression value (ETSI TS 101 154 page 99) */
- static INT decodeCompr(const UCHAR compr)
- {
- INT gain;
- SCHAR x = compr >> 4; /* 4 MSB of compr */
- UCHAR y = (compr & 0x0F); /* 4 LSB of compr */
- /* gain = (INT)((48.164f - 6.0206f * x - 0.4014f * y) ); */
- 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)) );
- return gain;
- }
- FDK_METADATA_ERROR FDK_MetadataEnc_Open(
- HANDLE_FDK_METADATA_ENCODER *phMetaData
- )
- {
- FDK_METADATA_ERROR err = METADATA_OK;
- HANDLE_FDK_METADATA_ENCODER hMetaData = NULL;
- if (phMetaData == NULL) {
- err = METADATA_INVALID_HANDLE;
- goto bail;
- }
- /* allocate memory */
- hMetaData = (HANDLE_FDK_METADATA_ENCODER) FDKcalloc(1, sizeof(FDK_METADATA_ENCODER) );
- if (hMetaData == NULL) {
- err = METADATA_MEMORY_ERROR;
- goto bail;
- }
- FDKmemclear(hMetaData, sizeof(FDK_METADATA_ENCODER));
- /* Allocate DRC Compressor. */
- if (FDK_DRC_Generator_Open(&hMetaData->hDrcComp)!=0) {
- err = METADATA_MEMORY_ERROR;
- goto bail;
- }
- /* Return metadata instance */
- *phMetaData = hMetaData;
- return err;
- bail:
- FDK_MetadataEnc_Close(&hMetaData);
- return err;
- }
- FDK_METADATA_ERROR FDK_MetadataEnc_Close(
- HANDLE_FDK_METADATA_ENCODER *phMetaData
- )
- {
- FDK_METADATA_ERROR err = METADATA_OK;
- if (phMetaData == NULL) {
- err = METADATA_INVALID_HANDLE;
- goto bail;
- }
- if (*phMetaData != NULL) {
- FDK_DRC_Generator_Close(&(*phMetaData)->hDrcComp);
- FDKfree(*phMetaData);
- *phMetaData = NULL;
- }
- bail:
- return err;
- }
- FDK_METADATA_ERROR 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
- )
- {
- FDK_METADATA_ERROR err = METADATA_OK;
- int i, nFrames, delay;
- if (hMetaData==NULL) {
- err = METADATA_INVALID_HANDLE;
- goto bail;
- }
- /* Determine values for delay compensation. */
- for (nFrames=0, delay=audioDelay-frameLength; delay>0; delay-=frameLength, nFrames++);
- if ( (hMetaData->nChannels>MAX_DRC_CHANNELS) || ((-delay)>MAX_DRC_FRAMELEN) ) {
- err = METADATA_INIT_ERROR;
- goto bail;
- }
- /* Initialize with default setup. */
- FDKmemcpy(&hMetaData->submittedMetaData, &defaultMetaDataSetup, sizeof(AACENC_MetaData));
- hMetaData->finalizeMetaData = 0; /* finalize meta data only while on/off switching, else disabled */
- /* Reset delay lines. */
- if ( resetStates || (hMetaData->nAudioDataDelay!=-delay) || (hMetaData->nChannels!=(INT)nChannels) )
- {
- FDKmemclear(hMetaData->audioDelayBuffer, sizeof(hMetaData->audioDelayBuffer));
- FDKmemclear(hMetaData->metaDataBuffer, sizeof(hMetaData->metaDataBuffer));
- hMetaData->audioDelayIdx = 0;
- hMetaData->metaDataDelayIdx = 0;
- }
- else {
- /* Enable meta data. */
- if ( (hMetaData->metadataMode==0) && (metadataMode!=0) ) {
- /* disable meta data in all delay lines */
- for (i=0; i<(int)(sizeof(hMetaData->metaDataBuffer)/sizeof(AAC_METADATA)); i++) {
- LoadSubmittedMetadata(&hMetaData->submittedMetaData, nChannels, 0, &hMetaData->metaDataBuffer[i]);
- }
- }
- /* Disable meta data.*/
- if ( (hMetaData->metadataMode!=0) && (metadataMode==0) ) {
- hMetaData->finalizeMetaData = hMetaData->metadataMode;
- }
- }
- /* Initialize delay. */
- hMetaData->nAudioDataDelay = -delay;
- hMetaData->nMetaDataDelay = nFrames;
- hMetaData->nChannels = nChannels;
- hMetaData->metadataMode = metadataMode;
- /* Initialize compressor. */
- if (metadataMode != 0) {
- if ( FDK_DRC_Generator_Initialize(
- hMetaData->hDrcComp,
- DRC_NONE,
- DRC_NONE,
- frameLength,
- sampleRate,
- channelMode,
- channelOrder,
- 1) != 0)
- {
- err = METADATA_INIT_ERROR;
- }
- }
- bail:
- return err;
- }
- static FDK_METADATA_ERROR ProcessCompressor(
- AAC_METADATA *pMetadata,
- HDRC_COMP hDrcComp,
- const INT_PCM * const pSamples,
- const INT nSamples
- )
- {
- FDK_METADATA_ERROR err = METADATA_OK;
- if ( (pMetadata==NULL) || (hDrcComp==NULL) ) {
- err = METADATA_INVALID_HANDLE;
- return err;
- }
- DRC_PROFILE profileDrc = convertProfile(pMetadata->mpegDrc.drc_profile);
- DRC_PROFILE profileComp = convertProfile(pMetadata->etsiAncData.comp_profile);
- /* first, check if profile is same as last frame
- * otherwise, update setup */
- if ( (profileDrc != FDK_DRC_Generator_getDrcProfile(hDrcComp))
- || (profileComp != FDK_DRC_Generator_getCompProfile(hDrcComp)) )
- {
- FDK_DRC_Generator_setDrcProfile(hDrcComp, profileDrc, profileComp);
- }
- /* Sanity check */
- if (profileComp == DRC_NONE) {
- pMetadata->etsiAncData.compression_value = 0x80; /* to ensure no external values will be written if not configured */
- }
- /* in case of embedding external values, copy this now (limiter may overwrite them) */
- INT dynrng = decodeDynrng(pMetadata->mpegDrc.dyn_rng_ctl[0], pMetadata->mpegDrc.dyn_rng_sgn[0]);
- INT compr = decodeCompr(pMetadata->etsiAncData.compression_value);
- /* Call compressor */
- if (FDK_DRC_Generator_Calc(hDrcComp,
- pSamples,
- progreflvl2dialnorm(pMetadata->mpegDrc.prog_ref_level),
- pMetadata->mpegDrc.drc_TargetRefLevel,
- pMetadata->etsiAncData.comp_TargetRefLevel,
- dmxTable[pMetadata->centerMixLevel],
- dmxTable[pMetadata->surroundMixLevel],
- &dynrng,
- &compr) != 0)
- {
- err = METADATA_ENCODE_ERROR;
- goto bail;
- }
- /* Write DRC values */
- pMetadata->mpegDrc.drc_band_incr = 0;
- encodeDynrng(dynrng, pMetadata->mpegDrc.dyn_rng_ctl, pMetadata->mpegDrc.dyn_rng_sgn);
- pMetadata->etsiAncData.compression_value = encodeCompr(compr);
- bail:
- return err;
- }
- FDK_METADATA_ERROR 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
- )
- {
- FDK_METADATA_ERROR err = METADATA_OK;
- int metaDataDelayWriteIdx, metaDataDelayReadIdx, metadataMode;
- /* Where to write new meta data info */
- metaDataDelayWriteIdx = hMetaDataEnc->metaDataDelayIdx;
- /* How to write the data */
- metadataMode = hMetaDataEnc->metadataMode;
- /* Compensate meta data delay. */
- hMetaDataEnc->metaDataDelayIdx++;
- if (hMetaDataEnc->metaDataDelayIdx > hMetaDataEnc->nMetaDataDelay) hMetaDataEnc->metaDataDelayIdx = 0;
- /* Where to read pending meta data info from. */
- metaDataDelayReadIdx = hMetaDataEnc->metaDataDelayIdx;
- /* Submit new data if available. */
- if (pMetadata!=NULL) {
- FDKmemcpy(&hMetaDataEnc->submittedMetaData, pMetadata, sizeof(AACENC_MetaData));
- }
- /* Write one additional frame with default configuration of meta data. Ensure defined behaviour on decoder side. */
- if ( (hMetaDataEnc->finalizeMetaData!=0) && (hMetaDataEnc->metadataMode==0)) {
- FDKmemcpy(&hMetaDataEnc->submittedMetaData, &defaultMetaDataSetup, sizeof(AACENC_MetaData));
- metadataMode = hMetaDataEnc->finalizeMetaData;
- hMetaDataEnc->finalizeMetaData = 0;
- }
- /* Get last submitted data. */
- if ( (err = LoadSubmittedMetadata(
- &hMetaDataEnc->submittedMetaData,
- hMetaDataEnc->nChannels,
- metadataMode,
- &hMetaDataEnc->metaDataBuffer[metaDataDelayWriteIdx])) != METADATA_OK )
- {
- goto bail;
- }
- /* Calculate compressor if necessary and updata meta data info */
- if (hMetaDataEnc->metaDataBuffer[metaDataDelayWriteIdx].metadataMode != 0) {
- if ( (err = ProcessCompressor(
- &hMetaDataEnc->metaDataBuffer[metaDataDelayWriteIdx],
- hMetaDataEnc->hDrcComp,
- pAudioSamples,
- nAudioSamples)) != METADATA_OK)
- {
- /* Get last submitted data again. */
- LoadSubmittedMetadata(
- &hMetaDataEnc->submittedMetaData,
- hMetaDataEnc->nChannels,
- metadataMode,
- &hMetaDataEnc->metaDataBuffer[metaDataDelayWriteIdx]);
- }
- }
- /* Convert Meta Data side info to bitstream data. */
- if ( (err = WriteMetadataPayload(hMetaDataEnc, &hMetaDataEnc->metaDataBuffer[metaDataDelayReadIdx])) != METADATA_OK ) {
- goto bail;
- }
- /* Assign meta data to output */
- *ppMetaDataExtPayload = hMetaDataEnc->exPayload;
- *nMetaDataExtensions = hMetaDataEnc->nExtensions;
- *matrix_mixdown_idx = hMetaDataEnc->matrix_mixdown_idx;
- bail:
- /* Compensate audio delay, reset err status. */
- err = CompensateAudioDelay(hMetaDataEnc, pAudioSamples, nAudioSamples);
- return err;
- }
- static FDK_METADATA_ERROR CompensateAudioDelay(
- HANDLE_FDK_METADATA_ENCODER hMetaDataEnc,
- INT_PCM * const pAudioSamples,
- const INT nAudioSamples
- )
- {
- FDK_METADATA_ERROR err = METADATA_OK;
- if (hMetaDataEnc->nAudioDataDelay) {
- int i, delaySamples = hMetaDataEnc->nAudioDataDelay*hMetaDataEnc->nChannels;
- for (i = 0; i < nAudioSamples; i++) {
- INT_PCM tmp = pAudioSamples[i];
- pAudioSamples[i] = hMetaDataEnc->audioDelayBuffer[hMetaDataEnc->audioDelayIdx];
- hMetaDataEnc->audioDelayBuffer[hMetaDataEnc->audioDelayIdx] = tmp;
- hMetaDataEnc->audioDelayIdx++;
- if (hMetaDataEnc->audioDelayIdx >= delaySamples) hMetaDataEnc->audioDelayIdx = 0;
- }
- }
- return err;
- }
- /*-----------------------------------------------------------------------------
- functionname: WriteMetadataPayload
- description: fills anc data and extension payload
- returns: Error status
- ------------------------------------------------------------------------------*/
- static FDK_METADATA_ERROR WriteMetadataPayload(
- const HANDLE_FDK_METADATA_ENCODER hMetaData,
- const AAC_METADATA * const pMetadata
- )
- {
- FDK_METADATA_ERROR err = METADATA_OK;
- if ( (hMetaData==NULL) || (pMetadata==NULL) ) {
- err = METADATA_INVALID_HANDLE;
- goto bail;
- }
- hMetaData->nExtensions = 0;
- hMetaData->matrix_mixdown_idx = -1;
- /* AAC-DRC */
- if (pMetadata->metadataMode != 0)
- {
- hMetaData->exPayload[hMetaData->nExtensions].pData = hMetaData->drcInfoPayload;
- hMetaData->exPayload[hMetaData->nExtensions].dataType = EXT_DYNAMIC_RANGE;
- hMetaData->exPayload[hMetaData->nExtensions].associatedChElement = -1;
- hMetaData->exPayload[hMetaData->nExtensions].dataSize =
- WriteDynamicRangeInfoPayload(pMetadata, hMetaData->exPayload[hMetaData->nExtensions].pData);
- hMetaData->nExtensions++;
- /* Matrix Mixdown Coefficient in PCE */
- if (pMetadata->WritePCEMixDwnIdx) {
- hMetaData->matrix_mixdown_idx = surmix2matrix_mixdown_idx[pMetadata->surroundMixLevel];
- }
- /* ETSI TS 101 154 (DVB) - MPEG4 ancillary_data() */
- if (pMetadata->metadataMode == 2) /* MP4_METADATA_MPEG_ETSI */
- {
- hMetaData->exPayload[hMetaData->nExtensions].pData = hMetaData->drcDsePayload;
- hMetaData->exPayload[hMetaData->nExtensions].dataType = EXT_DATA_ELEMENT;
- hMetaData->exPayload[hMetaData->nExtensions].associatedChElement = -1;
- hMetaData->exPayload[hMetaData->nExtensions].dataSize =
- WriteEtsiAncillaryDataPayload(pMetadata,hMetaData->exPayload[hMetaData->nExtensions].pData);
- hMetaData->nExtensions++;
- } /* metadataMode == 2 */
- } /* metadataMode != 0 */
- bail:
- return err;
- }
- static INT WriteDynamicRangeInfoPayload(
- const AAC_METADATA* const pMetadata,
- UCHAR* const pExtensionPayload
- )
- {
- const INT pce_tag_present = 0; /* yet fixed setting! */
- const INT prog_ref_lev_res_bits = 0;
- INT i, drc_num_bands = 1;
- FDK_BITSTREAM bsWriter;
- FDKinitBitStream(&bsWriter, pExtensionPayload, 16, 0, BS_WRITER);
- /* dynamic_range_info() */
- FDKwriteBits(&bsWriter, pce_tag_present, 1); /* pce_tag_present */
- if (pce_tag_present) {
- FDKwriteBits(&bsWriter, 0x0, 4); /* pce_instance_tag */
- FDKwriteBits(&bsWriter, 0x0, 4); /* drc_tag_reserved_bits */
- }
- /* Exclude channels */
- FDKwriteBits(&bsWriter, (pMetadata->mpegDrc.excluded_chns_present) ? 1 : 0, 1); /* excluded_chns_present*/
- /* Multiband DRC */
- FDKwriteBits(&bsWriter, (pMetadata->mpegDrc.drc_bands_present) ? 1 : 0, 1); /* drc_bands_present */
- if (pMetadata->mpegDrc.drc_bands_present)
- {
- FDKwriteBits(&bsWriter, pMetadata->mpegDrc.drc_band_incr, 4); /* drc_band_incr */
- FDKwriteBits(&bsWriter, pMetadata->mpegDrc.drc_interpolation_scheme, 4); /* drc_interpolation_scheme */
- drc_num_bands += pMetadata->mpegDrc.drc_band_incr;
- for (i=0; i<drc_num_bands; i++) {
- FDKwriteBits(&bsWriter, pMetadata->mpegDrc.drc_band_top[i], 8); /* drc_band_top */
- }
- }
- /* Program Reference Level */
- FDKwriteBits(&bsWriter, pMetadata->mpegDrc.prog_ref_level_present, 1); /* prog_ref_level_present */
- if (pMetadata->mpegDrc.prog_ref_level_present)
- {
- FDKwriteBits(&bsWriter, pMetadata->mpegDrc.prog_ref_level, 7); /* prog_ref_level */
- FDKwriteBits(&bsWriter, prog_ref_lev_res_bits, 1); /* prog_ref_level_reserved_bits */
- }
- /* DRC Values */
- for (i=0; i<drc_num_bands; i++) {
- FDKwriteBits(&bsWriter, (pMetadata->mpegDrc.dyn_rng_sgn[i]) ? 1 : 0, 1); /* dyn_rng_sgn[ */
- FDKwriteBits(&bsWriter, pMetadata->mpegDrc.dyn_rng_ctl[i], 7); /* dyn_rng_ctl */
- }
- /* return number of valid bits in extension payload. */
- return FDKgetValidBits(&bsWriter);
- }
- static INT WriteEtsiAncillaryDataPayload(
- const AAC_METADATA* const pMetadata,
- UCHAR* const pExtensionPayload
- )
- {
- FDK_BITSTREAM bsWriter;
- FDKinitBitStream(&bsWriter, pExtensionPayload, 16, 0, BS_WRITER);
- /* ancillary_data_sync */
- FDKwriteBits(&bsWriter, 0xBC, 8);
- /* bs_info */
- FDKwriteBits(&bsWriter, 0x3, 2); /* mpeg_audio_type */
- FDKwriteBits(&bsWriter, pMetadata->dolbySurroundMode, 2); /* dolby_surround_mode */
- FDKwriteBits(&bsWriter, 0x0, 4); /* reserved */
- /* ancillary_data_status */
- FDKwriteBits(&bsWriter, 0, 3); /* 3 bit Reserved, set to "0" */
- FDKwriteBits(&bsWriter, (pMetadata->DmxLvl_On) ? 1 : 0, 1); /* downmixing_levels_MPEG4_status */
- FDKwriteBits(&bsWriter, 0, 1); /* Reserved, set to "0" */
- FDKwriteBits(&bsWriter, (pMetadata->etsiAncData.compression_on) ? 1 : 0, 1); /* audio_coding_mode_and_compression status */
- FDKwriteBits(&bsWriter, (pMetadata->etsiAncData.timecode_coarse_status) ? 1 : 0, 1); /* coarse_grain_timecode_status */
- FDKwriteBits(&bsWriter, (pMetadata->etsiAncData.timecode_fine_status) ? 1 : 0, 1); /* fine_grain_timecode_status */
- /* downmixing_levels_MPEG4_status */
- if (pMetadata->DmxLvl_On) {
- FDKwriteBits(&bsWriter, encodeDmxLvls(pMetadata->centerMixLevel, pMetadata->surroundMixLevel), 8);
- }
- /* audio_coding_mode_and_compression_status */
- if (pMetadata->etsiAncData.compression_on) {
- FDKwriteBits(&bsWriter, 0x01, 8); /* audio coding mode */
- FDKwriteBits(&bsWriter, pMetadata->etsiAncData.compression_value, 8); /* compression value */
- }
- /* grain-timecode coarse/fine */
- if (pMetadata->etsiAncData.timecode_coarse_status) {
- FDKwriteBits(&bsWriter, 0x0, 16); /* not yet supported */
- }
- if (pMetadata->etsiAncData.timecode_fine_status) {
- FDKwriteBits(&bsWriter, 0x0, 16); /* not yet supported */
- }
- return FDKgetValidBits(&bsWriter);
- }
- static FDK_METADATA_ERROR LoadSubmittedMetadata(
- const AACENC_MetaData * const hMetadata,
- const INT nChannels,
- const INT metadataMode,
- AAC_METADATA * const pAacMetaData
- )
- {
- FDK_METADATA_ERROR err = METADATA_OK;
- if (pAacMetaData==NULL) {
- err = METADATA_INVALID_HANDLE;
- }
- else {
- /* init struct */
- FDKmemclear(pAacMetaData, sizeof(AAC_METADATA));
- if (hMetadata!=NULL) {
- /* convert data */
- pAacMetaData->mpegDrc.drc_profile = hMetadata->drc_profile;
- pAacMetaData->etsiAncData.comp_profile = hMetadata->comp_profile;
- pAacMetaData->mpegDrc.drc_TargetRefLevel = hMetadata->drc_TargetRefLevel;
- pAacMetaData->etsiAncData.comp_TargetRefLevel= hMetadata->comp_TargetRefLevel;
- pAacMetaData->mpegDrc.prog_ref_level_present = hMetadata->prog_ref_level_present;
- pAacMetaData->mpegDrc.prog_ref_level = dialnorm2progreflvl(hMetadata->prog_ref_level);
- pAacMetaData->centerMixLevel = hMetadata->centerMixLevel;
- pAacMetaData->surroundMixLevel = hMetadata->surroundMixLevel;
- pAacMetaData->WritePCEMixDwnIdx = hMetadata->PCE_mixdown_idx_present;
- pAacMetaData->DmxLvl_On = hMetadata->ETSI_DmxLvl_present;
- pAacMetaData->etsiAncData.compression_on = 1;
- if (nChannels == 2) {
- pAacMetaData->dolbySurroundMode = hMetadata->dolbySurroundMode; /* dolby_surround_mode */
- } else {
- pAacMetaData->dolbySurroundMode = 0;
- }
- pAacMetaData->etsiAncData.timecode_coarse_status = 0; /* not yet supported - attention: Update GetEstMetadataBytesPerFrame() if enable this! */
- pAacMetaData->etsiAncData.timecode_fine_status = 0; /* not yet supported - attention: Update GetEstMetadataBytesPerFrame() if enable this! */
- pAacMetaData->metadataMode = metadataMode;
- }
- else {
- pAacMetaData->metadataMode = 0; /* there is no configuration available */
- }
- }
- return err;
- }
- INT FDK_MetadataEnc_GetDelay(
- HANDLE_FDK_METADATA_ENCODER hMetadataEnc
- )
- {
- INT delay = 0;
- if (hMetadataEnc!=NULL) {
- delay = hMetadataEnc->nAudioDataDelay;
- }
- return delay;
- }
|