Commit 3c59acf1 authored by Jean-Michel Trivi's avatar Jean-Michel Trivi

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
parent fc4d7b0e
...@@ -98,7 +98,7 @@ amm-info@iis.fraunhofer.de ...@@ -98,7 +98,7 @@ amm-info@iis.fraunhofer.de
/* Encoder library info */ /* Encoder library info */
#define AACENCODER_LIB_VL0 3 #define AACENCODER_LIB_VL0 3
#define AACENCODER_LIB_VL1 4 #define AACENCODER_LIB_VL1 4
#define AACENCODER_LIB_VL2 4 #define AACENCODER_LIB_VL2 5
#define AACENCODER_LIB_TITLE "AAC Encoder" #define AACENCODER_LIB_TITLE "AAC Encoder"
#define AACENCODER_LIB_BUILD_DATE __DATE__ #define AACENCODER_LIB_BUILD_DATE __DATE__
#define AACENCODER_LIB_BUILD_TIME __TIME__ #define AACENCODER_LIB_BUILD_TIME __TIME__
...@@ -525,56 +525,58 @@ INT aacEncoder_LimitBitrate( ...@@ -525,56 +525,58 @@ INT aacEncoder_LimitBitrate(
/* Limit bit rate in respect to available SBR modes if active */ /* Limit bit rate in respect to available SBR modes if active */
if (sbrActive) if (sbrActive)
{ {
SBR_ELEMENT_INFO sbrElInfo[6]; int numIterations = 0;
INT sbrBitRate = 0; INT initialBitrate, adjustedBitrate;
int e, tooBig=-1; 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 */ initialBitrate = adjustedBitrate;
aacEncDistributeSbrBits(&cm, sbrElInfo, bitRate);
for (e=0; e<cm.nElements; e++) /* Get bit rate for each SBR element */
{ aacEncDistributeSbrBits(&cm, sbrElInfo, initialBitrate);
INT sbrElementBitRateIn, sbrBitRateOut;
if (cm.elInfo[e].elType != ID_SCE && cm.elInfo[e].elType != ID_CPE) { for (e=0; e<cm.nElements; e++)
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)
{ {
INT sbrBitRateLimit = (INT)fDivNorm((FIXP_DBL)sbrBitRateOut, cm.elInfo[e].relativeBits); INT sbrElementBitRateIn, sbrBitRateOut;
if (tooBig) {
sbrBitRate = fMin(sbrBitRate, sbrBitRateLimit-16); if (cm.elInfo[e].elType != ID_SCE && cm.elInfo[e].elType != ID_CPE) {
FDK_ASSERT( (INT)fMultNorm(cm.elInfo[e].relativeBits, (FIXP_DBL)sbrBitRate) < sbrBitRateOut); continue;
} else {
sbrBitRate = fMax(sbrBitRate, sbrBitRateLimit+16);
FDK_ASSERT( (INT)fMultNorm(cm.elInfo[e].relativeBits, (FIXP_DBL)sbrBitRate) >= sbrBitRateOut);
} }
} sbrElementBitRateIn = sbrElInfo[e].bitRate;
} sbrBitRateOut = sbrEncoder_LimitBitRate(sbrElementBitRateIn , cm.elInfo[e].nChannelsInEl, coreSamplingRate, aot);
if (tooBig != -1) { if (sbrBitRateOut == 0) {
bitRate = sbrBitRate; 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); FDK_ASSERT(bitRate > 0);
...@@ -840,7 +842,7 @@ static AACENC_ERROR aacEncInit(HANDLE_AACENCODER hAacEncoder, ...@@ -840,7 +842,7 @@ static AACENC_ERROR aacEncInit(HANDLE_AACENCODER hAacEncoder,
INT sbrError; INT sbrError;
SBR_ELEMENT_INFO sbrElInfo[(6)]; SBR_ELEMENT_INFO sbrElInfo[(6)];
CHANNEL_MAPPING channelMapping; CHANNEL_MAPPING channelMapping;
AUDIO_OBJECT_TYPE aot = hAacConfig->audioObjectType; AUDIO_OBJECT_TYPE aot = hAacConfig->audioObjectType;
if ( FDKaacEnc_InitChannelMapping(hAacConfig->channelMode, if ( FDKaacEnc_InitChannelMapping(hAacConfig->channelMode,
...@@ -1097,7 +1099,7 @@ AACENC_ERROR aacEncOpen( ...@@ -1097,7 +1099,7 @@ AACENC_ERROR aacEncOpen(
goto bail; goto bail;
} }
else { else {
C_ALLOC_SCRATCH_START(pLibInfo, LIB_INFO, FDK_MODULE_LAST); C_ALLOC_SCRATCH_START(pLibInfo, LIB_INFO, FDK_MODULE_LAST);
FDKinitLibInfo( pLibInfo); FDKinitLibInfo( pLibInfo);
transportEnc_GetLibInfo( pLibInfo ); transportEnc_GetLibInfo( pLibInfo );
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment