diff options
author | Jean-Michel Trivi <jmtrivi@google.com> | 2013-08-08 17:57:01 -0700 |
---|---|---|
committer | Jean-Michel Trivi <jmtrivi@google.com> | 2013-08-20 15:27:49 -0700 |
commit | 3c59acf1280ed5cbbf45a53743ea0ff635568769 (patch) | |
tree | 241fdfe8ccf990a3198d83a5afed369eaa880f36 /libAACenc/src/aacenc_lib.cpp | |
parent | fc4d7b0e73a87042f87ab847cfbe60e4d2dddf71 (diff) | |
download | fdk-aac-3c59acf1280ed5cbbf45a53743ea0ff635568769.tar.gz fdk-aac-3c59acf1280ed5cbbf45a53743ea0ff635568769.tar.bz2 fdk-aac-3c59acf1280ed5cbbf45a53743ea0ff635568769.zip |
AAC encoder bitrate limitation
AAC encoder: Make the bit rate limiting functionality more stable for multichannel
configurations where element bit rate for SBR can differ significantly.
Bug 9428126
Change-Id: I35b134c5b3c160a8f5a16b4314782b731fe49cd8
Diffstat (limited to 'libAACenc/src/aacenc_lib.cpp')
-rw-r--r-- | libAACenc/src/aacenc_lib.cpp | 96 |
1 files changed, 49 insertions, 47 deletions
diff --git a/libAACenc/src/aacenc_lib.cpp b/libAACenc/src/aacenc_lib.cpp index f298ab3..169400a 100644 --- a/libAACenc/src/aacenc_lib.cpp +++ b/libAACenc/src/aacenc_lib.cpp @@ -98,7 +98,7 @@ amm-info@iis.fraunhofer.de /* Encoder library info */ #define AACENCODER_LIB_VL0 3 #define AACENCODER_LIB_VL1 4 -#define AACENCODER_LIB_VL2 4 +#define AACENCODER_LIB_VL2 5 #define AACENCODER_LIB_TITLE "AAC Encoder" #define AACENCODER_LIB_BUILD_DATE __DATE__ #define AACENCODER_LIB_BUILD_TIME __TIME__ @@ -525,56 +525,58 @@ INT aacEncoder_LimitBitrate( /* 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; + int numIterations = 0; + INT initialBitrate, adjustedBitrate; + initialBitrate = adjustedBitrate = bitRate; - FDK_ASSERT(cm.nElements <= (6)); + /* Find total bitrate which provides valid configuration for each SBR element. */ + do { + int e; + SBR_ELEMENT_INFO sbrElInfo[(6)]; + FDK_ASSERT(cm.nElements <= (6)); - /* Get bit rate for each SBR element */ - aacEncDistributeSbrBits(&cm, sbrElInfo, bitRate); + initialBitrate = adjustedBitrate; - for (e=0; e<cm.nElements; e++) - { - INT sbrElementBitRateIn, sbrBitRateOut; + /* Get bit rate for each SBR element */ + aacEncDistributeSbrBits(&cm, sbrElInfo, initialBitrate); - if (cm.elInfo[e].elType != ID_SCE && cm.elInfo[e].elType != ID_CPE) { - continue; - } - sbrElementBitRateIn = sbrElInfo[e].bitRate; - sbrBitRateOut = sbrEncoder_LimitBitRate(sbrElementBitRateIn , cm.elInfo[e].nChannelsInEl, coreSamplingRate, aot); - if (sbrBitRateOut == 0) { - return 0; - } - if (sbrElementBitRateIn < sbrBitRateOut) { - FDK_ASSERT(tooBig != 1); - tooBig = 0; - if (e == 0) { - sbrBitRate = 0; - } - } - if (sbrElementBitRateIn > sbrBitRateOut) { - FDK_ASSERT(tooBig != 0); - tooBig = 1; - if (e == 0) { - sbrBitRate = 5000000; - } - } - if (tooBig != -1) + for (e=0; e<cm.nElements; e++) { - 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); + INT sbrElementBitRateIn, sbrBitRateOut; + + if (cm.elInfo[e].elType != ID_SCE && cm.elInfo[e].elType != ID_CPE) { + continue; } - } - } - if (tooBig != -1) { - bitRate = sbrBitRate; - } + sbrElementBitRateIn = sbrElInfo[e].bitRate; + sbrBitRateOut = sbrEncoder_LimitBitRate(sbrElementBitRateIn , cm.elInfo[e].nChannelsInEl, coreSamplingRate, aot); + if (sbrBitRateOut == 0) { + return 0; + } + + /* If bitrates don't match, distribution and limiting needs to be determined again. + Abort element loop and restart with adapted bitrate. */ + if (sbrElementBitRateIn != sbrBitRateOut) { + + if (sbrElementBitRateIn < sbrBitRateOut) { + adjustedBitrate = fMax(initialBitrate, (INT)fDivNorm((FIXP_DBL)(sbrBitRateOut+8), cm.elInfo[e].relativeBits)); + break; + } + + if (sbrElementBitRateIn > sbrBitRateOut) { + adjustedBitrate = fMin(initialBitrate, (INT)fDivNorm((FIXP_DBL)(sbrBitRateOut-8), cm.elInfo[e].relativeBits)); + break; + } + + } /* sbrElementBitRateIn != sbrBitRateOut */ + + } /* elements */ + + numIterations++; /* restrict iteration to worst case of num elements */ + + } while ( (initialBitrate!=adjustedBitrate) && (numIterations<=cm.nElements) ); + + /* Unequal bitrates mean that no reasonable bitrate configuration found. */ + bitRate = (initialBitrate==adjustedBitrate) ? adjustedBitrate : 0; } FDK_ASSERT(bitRate > 0); @@ -840,7 +842,7 @@ static AACENC_ERROR aacEncInit(HANDLE_AACENCODER hAacEncoder, INT sbrError; SBR_ELEMENT_INFO sbrElInfo[(6)]; CHANNEL_MAPPING channelMapping; - + AUDIO_OBJECT_TYPE aot = hAacConfig->audioObjectType; if ( FDKaacEnc_InitChannelMapping(hAacConfig->channelMode, @@ -1097,7 +1099,7 @@ AACENC_ERROR aacEncOpen( goto bail; } else { - C_ALLOC_SCRATCH_START(pLibInfo, LIB_INFO, FDK_MODULE_LAST); + C_ALLOC_SCRATCH_START(pLibInfo, LIB_INFO, FDK_MODULE_LAST); FDKinitLibInfo( pLibInfo); transportEnc_GetLibInfo( pLibInfo ); |