summaryrefslogtreecommitdiffstats
path: root/libAACenc/src/aacenc.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libAACenc/src/aacenc.cpp')
-rw-r--r--libAACenc/src/aacenc.cpp95
1 files changed, 56 insertions, 39 deletions
diff --git a/libAACenc/src/aacenc.cpp b/libAACenc/src/aacenc.cpp
index 5ab7192..c2c744f 100644
--- a/libAACenc/src/aacenc.cpp
+++ b/libAACenc/src/aacenc.cpp
@@ -43,48 +43,61 @@
+#define MIN_BUFSIZE_PER_EFF_CHAN 6144
+
static AAC_ENCODER_ERROR FDKaacEnc_InitCheckAncillary(INT bitRate,
INT framelength,
INT ancillaryRate,
INT *ancillaryBitsPerFrame,
INT sampleRate);
-/**
- * For calculating average bitrate of an access unit 32 bit data width is not sufficient
- * in worst case. Therefore use scaling of the samplingrate parameter to keep complete information.
- */
-typedef struct {
- INT samplingRate;
- UCHAR scalingFactor;
-} SR_SCALING_TAB;
-
-static const SR_SCALING_TAB samplingRateScalingTable[] =
+INT FDKaacEnc_LimitBitrate(
+ HANDLE_TRANSPORTENC hTpEnc,
+ INT coreSamplingRate,
+ INT frameLength,
+ INT nChannels,
+ INT nChannelsEff,
+ INT bitRate,
+ INT averageBits,
+ INT *pAverageBitsPerFrame,
+ INT bitrateMode,
+ INT nSubFrames
+ )
{
- { 8000, 5 }, { 11025, 0 }, { 12000, 5 }, { 16000, 5 },
- { 22050, 1 }, { 24000, 5 }, { 32000, 5 }, { 44100, 2 },
- { 48000, 5 }, { 64000, 5 }, { 88200, 3 }, { 96000, 5 }
-};
+ INT transportBits, prevBitRate, averageBitsPerFrame, shift = 0, iter=0;
-/**
- * Get maximal scaling factor without losing samplingrate accuracy.
- *
- * \param samplingRate Samplingrate to be used.
- * \return scaling value.
- */
-static int GetSrSf(const INT samplingRate)
-{
- int i, result = 0;
+ while ( (frameLength & ~((1<<(shift+1))-1)) == frameLength
+ && (coreSamplingRate & ~((1<<(shift+1))-1)) == coreSamplingRate )
+ {
+ shift ++;
+ }
- for (i=0; i<(int)(sizeof(samplingRateScalingTable)/sizeof(SR_SCALING_TAB)); i++) {
- if ( samplingRateScalingTable[i].samplingRate == samplingRate ) {
- result = samplingRateScalingTable[i].scalingFactor;
- break;
+ do {
+ prevBitRate = bitRate;
+ averageBitsPerFrame = (bitRate*(frameLength>>shift)) / (coreSamplingRate>>shift) / nSubFrames;
+
+ if (pAverageBitsPerFrame != NULL) {
+ *pAverageBitsPerFrame = averageBitsPerFrame;
}
- }
- return result;
+
+ if (hTpEnc != NULL) {
+ transportBits = transportEnc_GetStaticBits(hTpEnc, averageBitsPerFrame);
+ } else {
+ /* Assume some worst case */
+ transportBits = 208;
+ }
+
+ bitRate = FDKmax(bitRate, ((((40 * nChannels) + transportBits + frameLength) * (coreSamplingRate)) / frameLength) );
+ FDK_ASSERT(bitRate >= 0);
+
+ bitRate = FDKmin(bitRate, ((nChannelsEff * MIN_BUFSIZE_PER_EFF_CHAN)*(coreSamplingRate>>shift)) / (frameLength>>shift)) ;
+ FDK_ASSERT(bitRate >= 0);
+
+ } while (prevBitRate != bitRate && iter++ < 3) ;
+
+ return bitRate;
}
-#define MIN_BUFSIZE_PER_EFF_CHAN 6144
typedef struct
{
@@ -349,16 +362,20 @@ AAC_ENCODER_ERROR FDKaacEnc_Initialize(HANDLE_AAC_ENC hAacEnc,
/* check bit rate */
- /* check if bitRate is not too low or high */
- averageBitsPerFrame = (config->bitRate*(config->framelength>>GetSrSf(config->sampleRate))) / (config->sampleRate>>GetSrSf(config->sampleRate)) / config->nSubFrames;
-
- /* assume minimum static bits of 40 in each channel. */
- if ( (averageBitsPerFrame <= ((40*config->nChannels) + transportEnc_GetStaticBits(hTpEnc, averageBitsPerFrame))) ||
- ( ((config->bitRate*(config->framelength>>GetSrSf(config->sampleRate)))) >
- ((FDKaacEnc_GetChannelModeConfiguration(config->channelMode)->nChannelsEff * MIN_BUFSIZE_PER_EFF_CHAN))*(config->sampleRate>>GetSrSf(config->sampleRate)) )
- )
+ 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;
+ return AAC_ENC_UNSUPPORTED_BITRATE;
}
if (config->syntaxFlags & AC_ER_VCB11) {