diff options
Diffstat (limited to 'libAACenc/src/aacenc.cpp')
-rw-r--r-- | libAACenc/src/aacenc.cpp | 1081 |
1 files changed, 0 insertions, 1081 deletions
diff --git a/libAACenc/src/aacenc.cpp b/libAACenc/src/aacenc.cpp deleted file mode 100644 index 96668cc..0000000 --- a/libAACenc/src/aacenc.cpp +++ /dev/null @@ -1,1081 +0,0 @@ - -/* ----------------------------------------------------------------------------------------------------------- -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 -amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ - -/*************************** Fast MPEG AAC Audio Encoder ********************** - - Initial author: M. Schug / A. Groeschel - contents/description: fast aac coder functions - -******************************************************************************/ -#include <stdio.h> -#include "aacenc.h" - -#include "bitenc.h" -#include "interface.h" -#include "psy_configuration.h" -#include "psy_main.h" -#include "qc_main.h" -#include "bandwidth.h" -#include "channel_map.h" -#include "tns_func.h" -#include "aacEnc_ram.h" - -#include "genericStds.h" - - - - -#define MIN_BUFSIZE_PER_EFF_CHAN 6144 - -static AAC_ENCODER_ERROR FDKaacEnc_InitCheckAncillary(INT bitRate, - INT framelength, - INT ancillaryRate, - INT *ancillaryBitsPerFrame, - INT sampleRate); - -INT FDKaacEnc_LimitBitrate( - HANDLE_TRANSPORTENC hTpEnc, - INT coreSamplingRate, - INT frameLength, - INT nChannels, - INT nChannelsEff, - INT bitRate, - INT averageBits, - INT *pAverageBitsPerFrame, - INT bitrateMode, - INT nSubFrames - ) -{ - INT transportBits, prevBitRate, averageBitsPerFrame, shift = 0, iter=0; - - while ( (frameLength & ~((1<<(shift+1))-1)) == frameLength - && (coreSamplingRate & ~((1<<(shift+1))-1)) == coreSamplingRate ) - { - shift ++; - } - - do { - prevBitRate = bitRate; - averageBitsPerFrame = (bitRate*(frameLength>>shift)) / (coreSamplingRate>>shift) / nSubFrames; - //fprintf(stderr, "FDKaacEnc_LimitBitrate(): averageBitsPerFrame=%d, prevBitRate=%d, nSubFrames=%d\n", averageBitsPerFrame, prevBitRate, bitRate); - - if (pAverageBitsPerFrame != NULL) { - *pAverageBitsPerFrame = averageBitsPerFrame; - } - - if (hTpEnc != NULL) { - transportBits = transportEnc_GetStaticBits(hTpEnc, averageBitsPerFrame); - } else { - /* Assume some worst case */ - transportBits = 208; - } - - //fprintf(stderr, "FDKaacEnc_LimitBitrate(): transportBits=%d, FDKmax(%d, %d)\n", transportBits, bitRate, - // ((((40 * nChannels) + transportBits) * (coreSamplingRate)) / frameLength)); - bitRate = FDKmax(bitRate, ((((40 * nChannels) + transportBits) * (coreSamplingRate)) / frameLength) ); - FDK_ASSERT(bitRate >= 0); - - //fprintf(stderr, "FDKaacEnc_LimitBitrate(): FDKmin(%d, %d)\n", bitRate, ((nChannelsEff * MIN_BUFSIZE_PER_EFF_CHAN)*(coreSamplingRate>>shift)) / (frameLength>>shift)); - bitRate = FDKmin(bitRate, ((nChannelsEff * MIN_BUFSIZE_PER_EFF_CHAN)*(coreSamplingRate>>shift)) / (frameLength>>shift)) ; - FDK_ASSERT(bitRate >= 0); - - } while (prevBitRate != bitRate && iter++ < 3) ; - - //fprintf(stderr, "FDKaacEnc_LimitBitrate(): bitRate=%d\n", bitRate); - return bitRate; -} - - -typedef struct -{ - AACENC_BITRATE_MODE bitrateMode; - int chanBitrate[2]; /* mono/stereo settings */ -} CONFIG_TAB_ENTRY_VBR; - -static const CONFIG_TAB_ENTRY_VBR configTabVBR[] = { - {AACENC_BR_MODE_CBR, { 0, 0}} , - {AACENC_BR_MODE_VBR_1, { 32000, 20000}} , - {AACENC_BR_MODE_VBR_2, { 40000, 32000}} , - {AACENC_BR_MODE_VBR_3, { 56000, 48000}} , - {AACENC_BR_MODE_VBR_4, { 72000, 64000}} , - {AACENC_BR_MODE_VBR_5, {112000, 96000}} -}; - -/*----------------------------------------------------------------------------- - - functionname: FDKaacEnc_GetVBRBitrate - description: Get VBR bitrate from vbr quality - input params: int vbrQuality (VBR0, VBR1, VBR2) - channelMode - returns: vbr bitrate - - ------------------------------------------------------------------------------*/ -INT FDKaacEnc_GetVBRBitrate(INT bitrateMode, CHANNEL_MODE channelMode) -{ - INT bitrate = 0; - INT monoStereoMode = 0; /* default mono */ - - if (FDKaacEnc_GetMonoStereoMode(channelMode)==EL_MODE_STEREO) { - monoStereoMode = 1; - } - - switch((AACENC_BITRATE_MODE)bitrateMode){ - case AACENC_BR_MODE_VBR_1: - case AACENC_BR_MODE_VBR_2: - case AACENC_BR_MODE_VBR_3: - case AACENC_BR_MODE_VBR_4: - case AACENC_BR_MODE_VBR_5: - bitrate = configTabVBR[bitrateMode].chanBitrate[monoStereoMode]; - break; - case AACENC_BR_MODE_INVALID: - case AACENC_BR_MODE_CBR: - case AACENC_BR_MODE_SFR: - case AACENC_BR_MODE_FF: - default: - bitrate = 0; - break; - } - - /* convert channel bitrate to overall bitrate*/ - bitrate *= FDKaacEnc_GetChannelModeConfiguration(channelMode)->nChannelsEff; - - return bitrate; -} - -/** - * \brief Convert encoder bitreservoir value for transport library. - * - * \param bitrateMode Bitratemode used in current encoder instance. Se ::AACENC_BITRATE_MODE - * \param bitresTotal Encoder bitreservoir level in bits. - * - * \return Corrected bitreservoir level used in transport library. - */ -static INT FDKaacEnc_EncBitresToTpBitres( - const AACENC_BITRATE_MODE bitrateMode, - const INT bitresTotal - ) -{ - INT transporBitreservoir = 0; - - switch (bitrateMode) { - case AACENC_BR_MODE_CBR: - transporBitreservoir = bitresTotal; /* encoder bitreservoir level */ - break; - case AACENC_BR_MODE_VBR_1: - case AACENC_BR_MODE_VBR_2: - case AACENC_BR_MODE_VBR_3: - case AACENC_BR_MODE_VBR_4: - case AACENC_BR_MODE_VBR_5: - transporBitreservoir = FDK_INT_MAX; /* signal variable bitrate */ - break; - case AACENC_BR_MODE_FF: - case AACENC_BR_MODE_SFR: - transporBitreservoir = 0; /* super framing and fixed framing */ - break; /* without bitreservoir signaling */ - default: - case AACENC_BR_MODE_INVALID: - transporBitreservoir = 0; /* invalid configuration*/ - FDK_ASSERT(0); - } - - return transporBitreservoir; -} - -/*----------------------------------------------------------------------------- - - functionname: FDKaacEnc_AacInitDefaultConfig - description: gives reasonable default configuration - returns: --- - - ------------------------------------------------------------------------------*/ -void FDKaacEnc_AacInitDefaultConfig(AACENC_CONFIG *config) -{ - /* make thepre initialization of the structs flexible */ - FDKmemclear(config, sizeof(AACENC_CONFIG)); - - /* default ancillary */ - config->anc_Rate = 0; /* no ancillary data */ - config->ancDataBitRate = 0; /* no additional consumed bitrate */ - - /* default configurations */ - config->bitRate = -1; /* bitrate must be set*/ - config->averageBits = -1; /* instead of bitrate/s we can configure bits/superframe */ - config->bitrateMode = 0; - config->bandWidth = 0; /* get bandwidth from table */ - config->useTns = TNS_ENABLE_MASK; /* tns enabled completly */ - config->usePns = 1; /* depending on channelBitrate this might be set to 0 later */ - config->useIS = 1; /* Intensity Stereo Configuration */ - config->framelength = -1; /* Framesize not configured */ - config->syntaxFlags = 0; /* default syntax with no specialities */ - config->epConfig = -1; /* no ER syntax -> no additional error protection */ - config->nSubFrames = 1; /* default, no sub frames */ - config->channelOrder = CH_ORDER_MPEG; /* Use MPEG channel ordering. */ - config->channelMode = MODE_UNKNOWN; - config->minBitsPerFrame = -1; /* minum number of bits in each AU */ - config->maxBitsPerFrame = -1; /* minum number of bits in each AU */ - config->bitreservoir = -1; /* default, uninitialized value */ - - /* init tabs in fixpoint_math */ - InitLdInt(); - InitInvSqrtTab(); -} - - -/*--------------------------------------------------------------------------- - - functionname: FDKaacEnc_Open - description: allocate and initialize a new encoder instance - returns: error code - - ---------------------------------------------------------------------------*/ -AAC_ENCODER_ERROR FDKaacEnc_Open(HANDLE_AAC_ENC *phAacEnc, - const INT nElements, - const INT nChannels, - const INT nSubFrames) -{ - AAC_ENCODER_ERROR ErrorStatus; - AAC_ENC *hAacEnc = NULL; - UCHAR *dynamicRAM = NULL; - - if (phAacEnc==NULL) { - return AAC_ENC_INVALID_HANDLE; - } - - /* allocate encoder structure */ - hAacEnc = GetRam_aacEnc_AacEncoder(); - if (hAacEnc == NULL) { - ErrorStatus = AAC_ENC_NO_MEMORY; - goto bail; - } - FDKmemclear(hAacEnc, sizeof(AAC_ENC)); - - hAacEnc->dynamic_RAM = GetAACdynamic_RAM(); - dynamicRAM = (UCHAR*)hAacEnc->dynamic_RAM; - - /* allocate the Psy aud Psy Out structure */ - ErrorStatus = FDKaacEnc_PsyNew(&hAacEnc->psyKernel, - nElements, - nChannels - ,dynamicRAM - ); - if (ErrorStatus != AAC_ENC_OK) - goto bail; - - ErrorStatus = FDKaacEnc_PsyOutNew(hAacEnc->psyOut, - nElements, - nChannels, - nSubFrames - ,dynamicRAM - ); - if (ErrorStatus != AAC_ENC_OK) - goto bail; - - /* allocate the Q&C Out structure */ - ErrorStatus = FDKaacEnc_QCOutNew(hAacEnc->qcOut, - nElements, - nChannels, - nSubFrames - ,dynamicRAM - ); - if (ErrorStatus != AAC_ENC_OK) - goto bail; - - /* allocate the Q&C kernel */ - ErrorStatus = FDKaacEnc_QCNew(&hAacEnc->qcKernel, - nElements - ,dynamicRAM - ); - if (ErrorStatus != AAC_ENC_OK) - goto bail; - - hAacEnc->maxChannels = nChannels; - hAacEnc->maxElements = nElements; - hAacEnc->maxFrames = nSubFrames; - -bail: - *phAacEnc = hAacEnc; - return ErrorStatus; -} - - -AAC_ENCODER_ERROR FDKaacEnc_Initialize(HANDLE_AAC_ENC hAacEnc, - AACENC_CONFIG *config, /* pre-initialized config struct */ - HANDLE_TRANSPORTENC hTpEnc, - ULONG initFlags) -{ - AAC_ENCODER_ERROR ErrorStatus; - INT psyBitrate, tnsMask; //INT profile = 1; - CHANNEL_MAPPING *cm = NULL; - - INT qmbfac, qbw; - FIXP_DBL mbfac, bw_ratio; - QC_INIT qcInit; - INT averageBitsPerFrame = 0; - - if (config==NULL) - return AAC_ENC_INVALID_HANDLE; - - /******************* sanity checks *******************/ - - /* check config structure */ - if (config->nChannels < 1 || config->nChannels > (8)) { - return AAC_ENC_UNSUPPORTED_CHANNELCONFIG; - } - - /* check sample rate */ - switch (config->sampleRate) - { - case 8000: - case 11025: - case 12000: - case 16000: - case 22050: - case 24000: - case 32000: - case 44100: - case 48000: - case 64000: - case 88200: - case 96000: - break; - default: - return AAC_ENC_UNSUPPORTED_SAMPLINGRATE; - } - - /* bitrate has to be set */ - if (config->bitRate==-1) { - return AAC_ENC_UNSUPPORTED_BITRATE; - } - - INT superframe_size = 110*8*(config->bitRate/8000); - INT frames_per_superframe = 6; - INT staticBits = 0; - if((config->syntaxFlags & AC_DAB) && hTpEnc) { - staticBits = transportEnc_GetStaticBits(hTpEnc, 0); - switch(config->sampleRate) { - case 48000: - frames_per_superframe=6; - break; - case 32000: - frames_per_superframe=4; - break; - case 24000: - frames_per_superframe=3; - break; - case 16000: - frames_per_superframe=2; - break; - } - - //config->nSubFrames = frames_per_superframe; - //fprintf(stderr, "DAB+ superframe size=%d\n", superframe_size); - config->bitRate = (superframe_size - 16*(frames_per_superframe-1) - staticBits) * 1000/120; - //fprintf(stderr, "DAB+ tuned bitrate=%d\n", config->bitRate); - config->maxBitsPerFrame = (superframe_size - 16*(frames_per_superframe-1) - staticBits) / frames_per_superframe; - config->maxBitsPerFrame += 7; /*padding*/ - //config->bitreservoir=(superframe_size - 16*(frames_per_superframe-1) - staticBits - 2*8)/frames_per_superframe; - //fprintf(stderr, "DAB+ tuned maxBitsPerFrame=%d\n", (superframe_size - 16*(frames_per_superframe-1) - staticBits)/frames_per_superframe); - } - - /* check bit rate */ - - if (FDKaacEnc_LimitBitrate( - hTpEnc, - config->sampleRate, - config->framelength, - config->nChannels, - FDKaacEnc_GetChannelModeConfiguration(config->channelMode)->nChannelsEff, - config->bitRate, - config->averageBits, - &averageBitsPerFrame, - config->bitrateMode, - config->nSubFrames - ) != config->bitRate ) - { - return AAC_ENC_UNSUPPORTED_BITRATE; - } - - if (config->syntaxFlags & AC_ER_VCB11) { - return AAC_ENC_UNSUPPORTED_ER_FORMAT; - } - if (config->syntaxFlags & AC_ER_HCR) { - return AAC_ENC_UNSUPPORTED_ER_FORMAT; - } - - /* check frame length */ - switch (config->framelength) - { - case 1024: - case 960: //TODO: DRM - if ( config->audioObjectType == AOT_ER_AAC_LD - || config->audioObjectType == AOT_ER_AAC_ELD ) - { - return AAC_ENC_INVALID_FRAME_LENGTH; - } - break; - case 512: - case 480: - if ( config->audioObjectType != AOT_ER_AAC_LD - && config->audioObjectType != AOT_ER_AAC_ELD ) - { - return AAC_ENC_INVALID_FRAME_LENGTH; - } - break; - default: - return AAC_ENC_INVALID_FRAME_LENGTH; - } - - if (config->anc_Rate != 0) { - - ErrorStatus = FDKaacEnc_InitCheckAncillary(config->bitRate, - config->framelength, - config->anc_Rate, - &hAacEnc->ancillaryBitsPerFrame, - config->sampleRate); - if (ErrorStatus != AAC_ENC_OK) - goto bail; - - - /* update estimated consumed bitrate */ - config->ancDataBitRate += ( (hAacEnc->ancillaryBitsPerFrame * config->sampleRate) / config->framelength ); - - } - - /* maximal allowed DSE bytes in frame */ - { - /* fixpoint calculation*/ - INT q_res, encBitrate, sc; - FIXP_DBL tmp = fDivNorm(config->framelength, config->sampleRate, &q_res); - encBitrate = (config->bitRate/*-config->ancDataBitRate*/)- (INT)(config->nChannels*8000); - sc = CountLeadingBits(encBitrate); - config->maxAncBytesPerAU = FDKmin( (256), FDKmax(0,(INT)(fMultDiv2(tmp, (FIXP_DBL)(encBitrate<<sc))>>(-q_res+sc-1+3))) ); - } - - /* bind config to hAacEnc->config */ - hAacEnc->config = config; - - /* set hAacEnc->bitrateMode */ - hAacEnc->bitrateMode = (AACENC_BITRATE_MODE)config->bitrateMode; - - hAacEnc->encoderMode = config->channelMode; - - ErrorStatus = FDKaacEnc_InitChannelMapping(hAacEnc->encoderMode, config->channelOrder, &hAacEnc->channelMapping); - if (ErrorStatus != AAC_ENC_OK) - goto bail; - - cm = &hAacEnc->channelMapping; - - ErrorStatus = FDKaacEnc_DetermineBandWidth(&hAacEnc->config->bandWidth, - config->bandWidth, - config->bitRate - config->ancDataBitRate, - hAacEnc->bitrateMode, - config->sampleRate, - config->framelength, - cm, - hAacEnc->encoderMode); - if (ErrorStatus != AAC_ENC_OK) - goto bail; - - hAacEnc->bandwidth90dB = (INT)hAacEnc->config->bandWidth; - - tnsMask = config->useTns ? TNS_ENABLE_MASK : 0x0; - psyBitrate = config->bitRate - config->ancDataBitRate; - - ErrorStatus = FDKaacEnc_psyInit(hAacEnc->psyKernel, - hAacEnc->psyOut, - hAacEnc->maxFrames, - hAacEnc->maxChannels, - config->audioObjectType, - cm); - if (ErrorStatus != AAC_ENC_OK) - goto bail; - - ErrorStatus = FDKaacEnc_psyMainInit(hAacEnc->psyKernel, - config->audioObjectType, - cm, - config->sampleRate, - config->framelength, - psyBitrate, - tnsMask, - hAacEnc->bandwidth90dB, - config->usePns, - config->useIS, - config->syntaxFlags, - initFlags); - if (ErrorStatus != AAC_ENC_OK) - goto bail; - - ErrorStatus = FDKaacEnc_QCOutInit(hAacEnc->qcOut, hAacEnc->maxFrames, cm); - if (ErrorStatus != AAC_ENC_OK) - goto bail; - - - - qcInit.channelMapping = &hAacEnc->channelMapping; - qcInit.sceCpe = 0; - - if ((config->bitrateMode>=1) && (config->bitrateMode<=5)) { - qcInit.averageBits = (averageBitsPerFrame+7)&~7; - qcInit.bitRes = MIN_BUFSIZE_PER_EFF_CHAN*cm->nChannelsEff; - qcInit.maxBits = MIN_BUFSIZE_PER_EFF_CHAN*cm->nChannelsEff; - qcInit.minBits = 0; - } - else - { - int maxBitres; - qcInit.averageBits = (averageBitsPerFrame+7)&~7; - maxBitres = (MIN_BUFSIZE_PER_EFF_CHAN*cm->nChannelsEff) - qcInit.averageBits; - qcInit.bitRes = (config->bitreservoir!=-1) ? FDKmin(config->bitreservoir, maxBitres) : maxBitres; - //fprintf(stderr, "qcInit.bitRes=%d\n", qcInit.bitRes); - - qcInit.maxBits = fixMin(MIN_BUFSIZE_PER_EFF_CHAN*cm->nChannelsEff, ((averageBitsPerFrame+7)&~7)+qcInit.bitRes); - qcInit.maxBits = (config->maxBitsPerFrame!=-1) ? fixMin(qcInit.maxBits, config->maxBitsPerFrame) : qcInit.maxBits; - //fprintf(stderr, "qcInit.maxBits=%d\n", qcInit.maxBits); - - qcInit.minBits = fixMax(0, ((averageBitsPerFrame-1)&~7)-qcInit.bitRes-transportEnc_GetStaticBits(hTpEnc, ((averageBitsPerFrame+7)&~7)+qcInit.bitRes)); - qcInit.minBits = (config->minBitsPerFrame!=-1) ? fixMax(qcInit.minBits, config->minBitsPerFrame) : qcInit.minBits; - //fprintf(stderr, "qcInit.minBits=%d\n", qcInit.minBits); - } - - qcInit.sampleRate = config->sampleRate; - qcInit.advancedBitsToPe = isLowDelay(config->audioObjectType) ? 1 : 0 ; - qcInit.nSubFrames = config->nSubFrames; - qcInit.padding.paddingRest = config->sampleRate; - - /* Calc meanPe */ - bw_ratio = fDivNorm((FIXP_DBL)hAacEnc->bandwidth90dB, (FIXP_DBL)(config->sampleRate>>1), &qbw); - qbw = DFRACT_BITS-1-qbw; - /* qcInit.meanPe = 10.0f * FRAME_LEN_LONG * hAacEnc->bandwidth90dB/(config->sampleRate/2.0f); */ - qcInit.meanPe = fMult(bw_ratio, (FIXP_DBL)((10*config->framelength)<<16)) >> (qbw-15); - - /* Calc maxBitFac */ - mbfac = fDivNorm((MIN_BUFSIZE_PER_EFF_CHAN-744)*cm->nChannelsEff, qcInit.averageBits/qcInit.nSubFrames, &qmbfac); - qmbfac = DFRACT_BITS-1-qmbfac; - qcInit.maxBitFac = (qmbfac > 24) ? (mbfac >> (qmbfac - 24)):(mbfac << (24 - qmbfac)); - - switch(config->bitrateMode){ - case AACENC_BR_MODE_CBR: - qcInit.bitrateMode = QCDATA_BR_MODE_CBR; - break; - case AACENC_BR_MODE_VBR_1: - qcInit.bitrateMode = QCDATA_BR_MODE_VBR_1; - break; - case AACENC_BR_MODE_VBR_2: - qcInit.bitrateMode = QCDATA_BR_MODE_VBR_2; - break; - case AACENC_BR_MODE_VBR_3: - qcInit.bitrateMode = QCDATA_BR_MODE_VBR_3; - break; - case AACENC_BR_MODE_VBR_4: - qcInit.bitrateMode = QCDATA_BR_MODE_VBR_4; - break; - case AACENC_BR_MODE_VBR_5: - qcInit.bitrateMode = QCDATA_BR_MODE_VBR_5; - break; - case AACENC_BR_MODE_SFR: - qcInit.bitrateMode = QCDATA_BR_MODE_SFR; - break; - case AACENC_BR_MODE_FF: - qcInit.bitrateMode = QCDATA_BR_MODE_FF; - break; - default: - ErrorStatus = AAC_ENC_UNSUPPORTED_BITRATE_MODE; - goto bail; - } - - qcInit.invQuant = (config->useRequant)?2:0; - - /* maxIterations should be set to the maximum number of requantization iterations that are - * allowed before the crash recovery functionality is activated. This setting should be adjusted - * to the processing power available, i.e. to the processing power headroom in one frame that is - * still left after normal encoding without requantization. Please note that if activated this - * functionality is used most likely only in cases where the encoder is operating beyond - * recommended settings, i.e. the audio quality is suboptimal anyway. Activating the crash - * recovery does not further reduce audio quality significantly in these cases. */ - if ( (config->audioObjectType == AOT_ER_AAC_LD) || (config->audioObjectType == AOT_ER_AAC_ELD) ) { - qcInit.maxIterations = 2; - } - else - { - qcInit.maxIterations = 5; - } - - qcInit.bitrate = config->bitRate - config->ancDataBitRate; - - qcInit.staticBits = transportEnc_GetStaticBits(hTpEnc, qcInit.averageBits/qcInit.nSubFrames); - - ErrorStatus = FDKaacEnc_QCInit(hAacEnc->qcKernel, &qcInit); - if (ErrorStatus != AAC_ENC_OK) - goto bail; - - /* Map virtual aot's to intern aot used in bitstream writer. */ - switch (hAacEnc->config->audioObjectType) { - case AOT_MP2_AAC_LC: - case AOT_DABPLUS_AAC_LC: - hAacEnc->aot = AOT_AAC_LC; - break; - case AOT_MP2_SBR: - case AOT_DABPLUS_SBR: - hAacEnc->aot = AOT_SBR; - break; - case AOT_MP2_PS: - case AOT_DABPLUS_PS: - hAacEnc->aot = AOT_PS; - break; - default: - hAacEnc->aot = hAacEnc->config->audioObjectType; - } - - /* common things */ - - return AAC_ENC_OK; - -bail: - - return ErrorStatus; -} - - -/*--------------------------------------------------------------------------- - - functionname: FDKaacEnc_EncodeFrame - description: encodes one frame - returns: error code - - ---------------------------------------------------------------------------*/ -AAC_ENCODER_ERROR FDKaacEnc_EncodeFrame( HANDLE_AAC_ENC hAacEnc, /* encoder handle */ - HANDLE_TRANSPORTENC hTpEnc, - INT_PCM* RESTRICT inputBuffer, - INT* nOutBytes, - AACENC_EXT_PAYLOAD extPayload[MAX_TOTAL_EXT_PAYLOADS] - ) -{ - AAC_ENCODER_ERROR ErrorStatus; - int el, n, c=0; - UCHAR extPayloadUsed[MAX_TOTAL_EXT_PAYLOADS]; - - CHANNEL_MAPPING *cm = &hAacEnc->channelMapping; - - - - PSY_OUT *psyOut = hAacEnc->psyOut[c]; - QC_OUT *qcOut = hAacEnc->qcOut[c]; - - FDKmemclear(extPayloadUsed, MAX_TOTAL_EXT_PAYLOADS * sizeof(UCHAR)); - - qcOut->elementExtBits = 0; /* sum up all extended bit of each element */ - qcOut->staticBits = 0; /* sum up side info bits of each element */ - qcOut->totalNoRedPe = 0; /* sum up PE */ - - /* advance psychoacoustics */ - for (el=0; el<cm->nElements; el++) { - ELEMENT_INFO elInfo = cm->elInfo[el]; - //fprintf(stderr, "elInfo.elType=%d\n", elInfo.elType); - - if ( (elInfo.elType == ID_SCE) - || (elInfo.elType == ID_CPE) - || (elInfo.elType == ID_LFE) ) - { - int ch; - - /* update pointer!*/ - for(ch=0;ch<elInfo.nChannelsInEl;ch++) { - PSY_OUT_CHANNEL *psyOutChan = psyOut->psyOutElement[el]->psyOutChannel[ch]; - QC_OUT_CHANNEL *qcOutChan = qcOut->qcElement[el]->qcOutChannel[ch]; - - psyOutChan->mdctSpectrum = qcOutChan->mdctSpectrum; - psyOutChan->sfbSpreadEnergy = qcOutChan->sfbSpreadEnergy; - psyOutChan->sfbEnergy = qcOutChan->sfbEnergy; - psyOutChan->sfbEnergyLdData = qcOutChan->sfbEnergyLdData; - psyOutChan->sfbMinSnrLdData = qcOutChan->sfbMinSnrLdData; - psyOutChan->sfbThresholdLdData = qcOutChan->sfbThresholdLdData; - - } - - FDKaacEnc_psyMain(elInfo.nChannelsInEl, - hAacEnc->psyKernel->psyElement[el], - hAacEnc->psyKernel->psyDynamic, - hAacEnc->psyKernel->psyConf, - psyOut->psyOutElement[el], - inputBuffer, - cm->elInfo[el].ChannelIndex, - cm->nChannels - - ); - - /* FormFactor, Pe and staticBitDemand calculation */ - ErrorStatus = FDKaacEnc_QCMainPrepare(&elInfo, - hAacEnc->qcKernel->hAdjThr->adjThrStateElem[el], - psyOut->psyOutElement[el], - qcOut->qcElement[el], - hAacEnc->aot, - hAacEnc->config->syntaxFlags, - hAacEnc->config->epConfig); - - if (ErrorStatus != AAC_ENC_OK) - return ErrorStatus; - - /*-------------------------------------------- */ - - qcOut->qcElement[el]->extBitsUsed = 0; - qcOut->qcElement[el]->nExtensions = 0; - /* reset extension payload */ - FDKmemclear(&qcOut->qcElement[el]->extension, (1)*sizeof(QC_OUT_EXTENSION)); - - for ( n = 0; n < MAX_TOTAL_EXT_PAYLOADS; n++ ) { - if ( !extPayloadUsed[n] - && (extPayload[n].associatedChElement == el) - && (extPayload[n].dataSize > 0) - && (extPayload[n].pData != NULL) ) - { - int idx = qcOut->qcElement[el]->nExtensions++; - - qcOut->qcElement[el]->extension[idx].type = extPayload[n].dataType; /* Perform a sanity check on the type? */ - qcOut->qcElement[el]->extension[idx].nPayloadBits = extPayload[n].dataSize; - qcOut->qcElement[el]->extension[idx].pPayload = extPayload[n].pData; - /* Now ask the bitstream encoder how many bits we need to encode the data with the current bitstream syntax: */ - qcOut->qcElement[el]->extBitsUsed += - FDKaacEnc_writeExtensionData( NULL, - &qcOut->qcElement[el]->extension[idx], - 0, 0, - hAacEnc->config->syntaxFlags, - hAacEnc->aot, - hAacEnc->config->epConfig ); - extPayloadUsed[n] = 1; - } - } - - /* sum up extension and static bits for all channel elements */ - qcOut->elementExtBits += qcOut->qcElement[el]->extBitsUsed; - qcOut->staticBits += qcOut->qcElement[el]->staticBitsUsed; - - /* sum up pe */ - qcOut->totalNoRedPe += qcOut->qcElement[el]->peData.pe; - } - } - - qcOut->nExtensions = 0; - qcOut->globalExtBits = 0; - - /* reset extension payload */ - FDKmemclear(&qcOut->extension, (2+2)*sizeof(QC_OUT_EXTENSION)); - - /* Add extension payload not assigned to an channel element - (Ancillary data is the only supported type up to now) */ - for ( n = 0; n < MAX_TOTAL_EXT_PAYLOADS; n++ ) { - if ( !extPayloadUsed[n] - && (extPayload[n].associatedChElement == -1) - && (extPayload[n].pData != NULL) ) - { - UINT payloadBits = 0; - - if (extPayload[n].dataType == EXT_DATA_ELEMENT) { - if (hAacEnc->ancillaryBitsPerFrame) { - /* granted frame dse bitrate */ - payloadBits = hAacEnc->ancillaryBitsPerFrame; - } - else { - /* write anc data if bitrate constraint fulfilled */ - if ((extPayload[n].dataSize>>3) <= hAacEnc->config->maxAncBytesPerAU) { - payloadBits = extPayload[n].dataSize; - } - } - payloadBits = fixMin( extPayload[n].dataSize, payloadBits ); - } else { - payloadBits = extPayload[n].dataSize; - } - - if (payloadBits > 0) - { - int idx = qcOut->nExtensions++; - - qcOut->extension[idx].type = extPayload[n].dataType; /* Perform a sanity check on the type? */ - qcOut->extension[idx].nPayloadBits = payloadBits; - qcOut->extension[idx].pPayload = extPayload[n].pData; - /* Now ask the bitstream encoder how many bits we need to encode the data with the current bitstream syntax: */ - qcOut->globalExtBits += FDKaacEnc_writeExtensionData( NULL, - &qcOut->extension[idx], - 0, 0, - hAacEnc->config->syntaxFlags, - hAacEnc->aot, - hAacEnc->config->epConfig ); - if (extPayload[n].dataType == EXT_DATA_ELEMENT) { - /* substract the processed bits */ - extPayload[n].dataSize -= payloadBits; - } - extPayloadUsed[n] = 1; - } - } - } - - if (!(hAacEnc->config->syntaxFlags & (AC_SCALABLE|AC_ER))) { - qcOut->globalExtBits += EL_ID_BITS; /* add bits for ID_END */ - } - - /* build bitstream all nSubFrames */ - { - INT totalBits = 0; /* Total AU bits */; - INT avgTotalBits = 0; - - /*-------------------------------------------- */ - /* Get average total bits */ - /*-------------------------------------------- */ - { - /* frame wise bitrate adaption */ - FDKaacEnc_AdjustBitrate(hAacEnc->qcKernel, - cm, - &avgTotalBits, - hAacEnc->config->bitRate, - hAacEnc->config->sampleRate, - hAacEnc->config->framelength); - - /* adjust super frame bitrate */ - avgTotalBits *= hAacEnc->config->nSubFrames; - //fprintf(stderr, "avgTotalBits=%d x %d\n", avgTotalBits, hAacEnc->config->nSubFrames); - } - - /* Make first estimate of transport header overhead. - Take maximum possible frame size into account to prevent bitreservoir underrun. */ - - //fprintf(stderr, "avgTotalBits=%d, bitResTot=%d\n", avgTotalBits, hAacEnc->qcKernel->bitResTot); - hAacEnc->qcKernel->globHdrBits = transportEnc_GetStaticBits(hTpEnc, avgTotalBits + hAacEnc->qcKernel->bitResTot); - - - /*-------------------------------------------- */ - /*-------------------------------------------- */ - /*-------------------------------------------- */ - - ErrorStatus = FDKaacEnc_QCMain(hAacEnc->qcKernel, - hAacEnc->psyOut, - hAacEnc->qcOut, - avgTotalBits, - cm - ,hAacEnc->aot, - hAacEnc->config->syntaxFlags, - hAacEnc->config->epConfig); - - if (ErrorStatus != AAC_ENC_OK) - return ErrorStatus; - /*-------------------------------------------- */ - - /*-------------------------------------------- */ - ErrorStatus = FDKaacEnc_updateFillBits(cm, - hAacEnc->qcKernel, - hAacEnc->qcKernel->elementBits, - hAacEnc->qcOut); - if (ErrorStatus != AAC_ENC_OK) - return ErrorStatus; - - /*-------------------------------------------- */ - ErrorStatus = FDKaacEnc_FinalizeBitConsumption(cm, - hAacEnc->qcKernel, - qcOut, - qcOut->qcElement, - hTpEnc, - hAacEnc->aot, - hAacEnc->config->syntaxFlags, - hAacEnc->config->epConfig); - if (ErrorStatus != AAC_ENC_OK) - return ErrorStatus; - /*-------------------------------------------- */ - totalBits += qcOut->totalBits; - - - /*-------------------------------------------- */ - FDKaacEnc_updateBitres(cm, - hAacEnc->qcKernel, - hAacEnc->qcOut); - - /*-------------------------------------------- */ - - /* for ( all sub frames ) ... */ - //fprintf(stderr, "totalBits=%d, qcOut->totalBits=%d, qcOut->totFillBits=%d\n", totalBits, qcOut->totalBits, qcOut->totFillBits); - /* write bitstream header */ - transportEnc_WriteAccessUnit( - hTpEnc, - totalBits, - FDKaacEnc_EncBitresToTpBitres(hAacEnc->bitrateMode, hAacEnc->qcKernel->bitResTot), - cm->nChannelsEff); - - /* write bitstream */ - ErrorStatus = FDKaacEnc_WriteBitstream( - hTpEnc, - cm, - qcOut, - psyOut, - hAacEnc->qcKernel, - hAacEnc->aot, - hAacEnc->config->syntaxFlags, - hAacEnc->config->epConfig); - - if (ErrorStatus != AAC_ENC_OK) - return ErrorStatus; - - /* transportEnc_EndAccessUnit() is being called inside FDKaacEnc_WriteBitstream() */ - transportEnc_GetFrame(hTpEnc, nOutBytes); - - } /* -end- if (curFrame==hAacEnc->qcKernel->nSubFrames) */ - - - /*-------------------------------------------- */ - return AAC_ENC_OK; -} - -/*--------------------------------------------------------------------------- - - functionname:FDKaacEnc_Close - description: delete encoder instance - returns: - - ---------------------------------------------------------------------------*/ - -void FDKaacEnc_Close( HANDLE_AAC_ENC* phAacEnc) /* encoder handle */ -{ - if (*phAacEnc == NULL) { - return; - } - AAC_ENC *hAacEnc = (AAC_ENC*)*phAacEnc; - - if (hAacEnc->dynamic_RAM != NULL) - FreeAACdynamic_RAM(&hAacEnc->dynamic_RAM); - - FDKaacEnc_PsyClose(&hAacEnc->psyKernel,hAacEnc->psyOut); - - FDKaacEnc_QCClose(&hAacEnc->qcKernel, hAacEnc->qcOut); - - FreeRam_aacEnc_AacEncoder(phAacEnc); -} - - -/* The following functions are in this source file only for convenience and */ -/* need not be visible outside of a possible encoder library. */ - -/* basic defines for ancillary data */ -#define MAX_ANCRATE 19200 /* ancillary rate >= 19200 isn't valid */ - -/*--------------------------------------------------------------------------- - - functionname: FDKaacEnc_InitCheckAncillary - description: initialize and check ancillary data struct - return: if success or NULL if error - - ---------------------------------------------------------------------------*/ -static AAC_ENCODER_ERROR FDKaacEnc_InitCheckAncillary(INT bitRate, - INT framelength, - INT ancillaryRate, - INT *ancillaryBitsPerFrame, - INT sampleRate) -{ - INT diffToByteAlign; - - /* don't use negative ancillary rates */ - if ( ancillaryRate < -1 ) - return AAC_ENC_UNSUPPORTED_ANC_BITRATE; - - /* check if ancillary rate is ok */ - if ( (ancillaryRate != (-1)) && (ancillaryRate != 0) ) { - /* ancRate <= 15% of bitrate && ancRate < 19200 */ - if ( ( ancillaryRate >= MAX_ANCRATE ) || - ( (ancillaryRate * 20) > (bitRate * 3) ) ) { - return AAC_ENC_UNSUPPORTED_ANC_BITRATE; - } - } - else if (ancillaryRate == -1) { - /* if no special ancRate is requested but a ancillary file is - stated, then generate a ancillary rate matching to the bitrate */ - if (bitRate >= (MAX_ANCRATE * 10)) { - /* ancillary rate is 19199 */ - ancillaryRate = (MAX_ANCRATE - 1); - } - else { /* 10% of bitrate */ - ancillaryRate = bitRate / 10; - } - } - - /* make ancillaryBitsPerFrame byte align */ - *ancillaryBitsPerFrame = (ancillaryRate * framelength ) / sampleRate; - diffToByteAlign = *ancillaryBitsPerFrame % 8; - *ancillaryBitsPerFrame = *ancillaryBitsPerFrame - diffToByteAlign; - - return AAC_ENC_OK; -} |