From 698b536f3b34a7cfc41a80e1034cc359456bdd66 Mon Sep 17 00:00:00 2001 From: Dave Burke Date: Sat, 12 May 2012 13:17:25 -0700 Subject: Update to 2012_05_11 version. Fixes: - Don't throw error for invalid bitrate but limit to functional value - More robust ASC parsing - More robust handling of corrupt bitstreams - Handle multiple raw access units Change-Id: Ib49fe2545ff4185fe924126da702fe84ac5c2d87 --- libAACenc/src/aacenc_lib.cpp | 164 ++++++++++++++++++++++++++++++++++++++----- 1 file changed, 147 insertions(+), 17 deletions(-) (limited to 'libAACenc/src/aacenc_lib.cpp') diff --git a/libAACenc/src/aacenc_lib.cpp b/libAACenc/src/aacenc_lib.cpp index 65a9bfc..7984c13 100644 --- a/libAACenc/src/aacenc_lib.cpp +++ b/libAACenc/src/aacenc_lib.cpp @@ -388,6 +388,138 @@ AAC_ENCODER_ERROR aacEncDefaultConfig(HANDLE_AACENC_CONFIG hAacConfig, return AAC_ENC_OK; } +static +void aacEncDistributeSbrBits(CHANNEL_MAPPING *channelMapping, SBR_ELEMENT_INFO *sbrElInfo, INT bitRate) +{ + INT codebits = bitRate; + int el; + + /* Copy Element info */ + for (el=0; elnElements; el++) { + sbrElInfo[el].ChannelIndex[0] = channelMapping->elInfo[el].ChannelIndex[0]; + sbrElInfo[el].ChannelIndex[1] = channelMapping->elInfo[el].ChannelIndex[1]; + sbrElInfo[el].elType = channelMapping->elInfo[el].elType; + sbrElInfo[el].bitRate = (INT)(fMultNorm(channelMapping->elInfo[el].relativeBits, (FIXP_DBL)bitRate)); + sbrElInfo[el].instanceTag = channelMapping->elInfo[el].instanceTag; + sbrElInfo[el].nChannelsInEl = channelMapping->elInfo[el].nChannelsInEl; + + codebits -= sbrElInfo[el].bitRate; + } + sbrElInfo[0].bitRate += codebits; +} + + +static +INT aacEncoder_LimitBitrate( + const HANDLE_TRANSPORTENC hTpEnc, + const INT samplingRate, + const INT frameLength, + const INT nChannels, + const CHANNEL_MODE channelMode, + INT bitRate, + const INT nSubFrames, + const INT sbrActive, + const AUDIO_OBJECT_TYPE aot + ) +{ + INT coreSamplingRate; + CHANNEL_MAPPING cm; + + FDKaacEnc_InitChannelMapping(channelMode, CH_ORDER_MPEG, &cm); + + if (sbrActive) { + /* Assume SBR rate ratio of 2:1 */ + coreSamplingRate = samplingRate / 2; + } else { + coreSamplingRate = samplingRate; + } + + /* Consider bandwidth channel bit rate limit (see bandwidth.cpp: GetBandwidthEntry()) */ + if (aot == AOT_ER_AAC_LD || aot == AOT_ER_AAC_ELD) { + bitRate = FDKmin(360000*nChannels, bitRate); + bitRate = FDKmax(8000*nChannels, bitRate); + } + + if (aot == AOT_AAC_LC || aot == AOT_SBR || aot == AOT_PS) { + bitRate = FDKmin(576000*nChannels, bitRate); + /*bitRate = FDKmax(0*nChannels, bitRate);*/ + } + + + /* Limit bit rate in respect to the core coder */ + bitRate = FDKaacEnc_LimitBitrate( + hTpEnc, + coreSamplingRate, + frameLength, + nChannels, + cm.nChannelsEff, + bitRate, + -1, + NULL, + -1, + nSubFrames + ); + + /* Limit bit rate in respect to available SBR modes if active */ + if (sbrActive) + { + SBR_ELEMENT_INFO sbrElInfo[6]; + INT sbrBitRate = 0; + int e, tooBig=-1; + + FDK_ASSERT(cm.nElements <= (6)); + + /* Get bit rate for each SBR element */ + aacEncDistributeSbrBits(&cm, sbrElInfo, bitRate); + + for (e=0; e sbrBitRateOut) { + FDK_ASSERT(tooBig != 0); + tooBig = 1; + if (e == 0) { + sbrBitRate = 5000000; + } + } + if (tooBig != -1) + { + INT sbrBitRateLimit = (INT)fDivNorm((FIXP_DBL)sbrBitRateOut, cm.elInfo[e].relativeBits); + if (tooBig) { + sbrBitRate = fMin(sbrBitRate, sbrBitRateLimit-16); + FDK_ASSERT( (INT)fMultNorm(cm.elInfo[e].relativeBits, (FIXP_DBL)sbrBitRate) < sbrBitRateOut); + } else { + sbrBitRate = fMax(sbrBitRate, sbrBitRateLimit+16); + FDK_ASSERT( (INT)fMultNorm(cm.elInfo[e].relativeBits, (FIXP_DBL)sbrBitRate) >= sbrBitRateOut); + } + } + } + if (tooBig != -1) { + bitRate = sbrBitRate; + } + } + + FDK_ASSERT(bitRate > 0); + + return bitRate; +} + /* * \brief Consistency check of given USER_PARAM struct and * copy back configuration from public struct into internal @@ -482,6 +614,19 @@ AACENC_ERROR FDKaacEnc_AdjustEncSettings(HANDLE_AACENCODER hAacEncoder, break; } + /* We need the frame length to call aacEncoder_LimitBitrate() */ + hAacConfig->bitRate = aacEncoder_LimitBitrate( + NULL, + hAacConfig->sampleRate, + hAacConfig->framelength, + hAacConfig->nChannels, + hAacConfig->channelMode, + config->userBitrate, + hAacConfig->nSubFrames, + isSbrActive(hAacConfig), + hAacConfig->audioObjectType + ); + switch ( hAacConfig->audioObjectType ) { case AOT_ER_AAC_LD: case AOT_ER_AAC_ELD: @@ -605,7 +750,6 @@ static AACENC_ERROR aacEncInit(HANDLE_AACENCODER hAacEncoder, INT frameLength = hAacConfig->framelength; - if ( (InitFlags & AACENC_INIT_CONFIG) ) { CHANNEL_MODE prevChMode = hAacConfig->channelMode; @@ -645,9 +789,7 @@ static AACENC_ERROR aacEncInit(HANDLE_AACENCODER hAacEncoder, INT sbrError; SBR_ELEMENT_INFO sbrElInfo[(6)]; CHANNEL_MAPPING channelMapping; - int el; - INT codebits = hAacConfig->bitRate; - INT bitrateSc = CountLeadingBits(codebits); + AUDIO_OBJECT_TYPE aot = hAacConfig->audioObjectType; if ( FDKaacEnc_InitChannelMapping(hAacConfig->channelMode, @@ -662,19 +804,7 @@ static AACENC_ERROR aacEncInit(HANDLE_AACENCODER hAacEncoder, return AACENC_INIT_ERROR; } - /* Copy Element info */ - for (el=0; elbitRate<>(bitrateSc)); - sbrElInfo[el].instanceTag = channelMapping.elInfo[el].instanceTag; - sbrElInfo[el].nChannelsInEl = channelMapping.elInfo[el].nChannelsInEl; - - sbrElInfo[el].bitRate = fMult(channelMapping.elInfo[el].relativeBits, (FIXP_DBL)hAacConfig->bitRate); - codebits -= sbrElInfo[el].bitRate; - } - sbrElInfo[0].bitRate += codebits; + aacEncDistributeSbrBits(&channelMapping, sbrElInfo, hAacConfig->bitRate); UINT initFlag = 0; initFlag += (InitFlags & AACENC_INIT_STATES) ? 1 : 0; -- cgit v1.2.3