ref: 0eaa3913655fe91a36b8c0245654b033ab8af12e
parent: 8240086c01ef272528c0fda0d79acc6dd0b8e4eb
author: corrados <corrados>
date: Sun Jul 18 05:34:24 EDT 2004
New bandwidth settings for DRM, improved quantization quality adaptation (almost constant bit-rate now)
--- a/libfaac/frame.c
+++ b/libfaac/frame.c
@@ -16,7 +16,7 @@
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
- * $Id: frame.c,v 1.64 2004/07/13 17:56:37 corrados Exp $
+ * $Id: frame.c,v 1.65 2004/07/18 09:34:24 corrados Exp $
*/
/*
@@ -180,18 +180,23 @@
int cutoff;
} rates[] = {
#ifdef DRM
- /* DRM needs lower bit-rates. We've chosen higher bandwidth values and
+ /* DRM uses low bit-rates. We've chosen higher bandwidth values and
decrease the quantizer quality at the same time to preserve the
low bit-rate */
- {7000, 1500},
- {15000, 3000},
- {23000, 4000},
-#endif
+ {4500, 1200},
+ {9180, 2500},
+ {11640, 3000},
+ {14500, 4000},
+ {17460, 5500},
+ {20960, 6250},
+ {40000, 12000},
+#else
{29500, 5000},
{37500, 7000},
{47000, 10000},
{64000, 16000},
{76000, 20000},
+#endif
{0, 0}
};
@@ -199,12 +204,12 @@
int r0, r1;
#ifdef DRM
- config->quantqual = 40; /* init with a lower value for DRM */
+ double tmpbitRate = (double)config->bitRate;
#else
- config->quantqual = 100;
+ double tmpbitRate = (double)config->bitRate * 44100 / hEncoder->sampleRate;
#endif
- config->bitRate = (double)config->bitRate * 44100 / hEncoder->sampleRate;
+ config->quantqual = 100;
f0 = f1 = rates[0].cutoff;
r0 = r1 = rates[0].rate;
@@ -215,25 +220,27 @@
f1 = rates[i].cutoff;
r0 = r1;
r1 = rates[i].rate;
- if (rates[i].rate >= config->bitRate)
+ if (rates[i].rate >= tmpbitRate)
break;
}
- if (config->bitRate > r1)
- config->bitRate = r1;
- if (config->bitRate < r0)
- config->bitRate = r0;
+ if (tmpbitRate > r1)
+ tmpbitRate = r1;
+ if (tmpbitRate < r0)
+ tmpbitRate = r0;
if (f1 > f0)
config->bandWidth =
- pow((double)config->bitRate / r1,
+ pow((double)tmpbitRate / r1,
log((double)f1 / f0) / log ((double)r1 / r0)) * (double)f1;
else
config->bandWidth = f1;
+#ifndef DRM
config->bandWidth =
(double)config->bandWidth * hEncoder->sampleRate / 44100;
- config->bitRate = (double)config->bitRate * hEncoder->sampleRate / 44100;
+ config->bitRate = tmpbitRate * hEncoder->sampleRate / 44100;
+#endif
if (config->bandWidth > bwbase)
config->bandWidth = bwbase;
@@ -447,6 +454,10 @@
BitStream *bitStream; /* bitstream used for writing the frame to */
TnsInfo *tnsInfo_for_LTP;
TnsInfo *tnsDecInfo;
+#ifdef DRM
+ int desbits, diff;
+ double fix;
+#endif
/* local copy's of parameters */
ChannelInfo *channelInfo = hEncoder->channelInfo;
@@ -738,6 +749,12 @@
MSEncode(coderInfo, channelInfo, hEncoder->freqBuff, numChannels, allowMidside);
+#ifdef DRM
+ /* loop the quantization until the desired bit-rate is reached */
+ diff = 1; /* to enter while loop */
+ hEncoder->aacquantCfg.quality = 120; /* init quality setting */
+ while (diff > 0) { /* if too many bits, do it again */
+#endif
/* Quantize and code the signal */
for (channel = 0; channel < numChannels; channel++) {
if (coderInfo[channel].block_type == ONLY_SHORT_WINDOW) {
@@ -753,6 +770,35 @@
}
}
+#ifdef DRM
+ /* Write the AAC bitstream */
+ bitStream = OpenBitStream(bufferSize, outputBuffer);
+ WriteBitstream(hEncoder, coderInfo, channelInfo, bitStream, numChannels);
+
+ /* Close the bitstream and return the number of bytes written */
+ frameBytes = CloseBitStream(bitStream);
+
+ /* now calculate desired bits and compare with actual encoded bits */
+ desbits = (int) ((double) numChannels * (hEncoder->config.bitRate * FRAME_LEN)
+ / hEncoder->sampleRate);
+
+ diff = ((frameBytes - 1 /* CRC */) * 8) - desbits;
+
+ /* do linear correction according to relative difference */
+ fix = (double) desbits / ((frameBytes - 1 /* CRC */) * 8);
+
+ /* speed up convergence. A value of 0.92 gives approx up to 10 iterations */
+ if (fix > 0.92)
+ fix = 0.92;
+
+ hEncoder->aacquantCfg.quality *= fix;
+
+ /* quality should not go lower than 1, set diff to exit loop */
+ if (hEncoder->aacquantCfg.quality <= 1)
+ diff = -1;
+ }
+#endif
+
// fix max_sfb in CPE mode
for (channel = 0; channel < numChannels; channel++)
{
@@ -811,6 +857,7 @@
}
}
+#ifndef DRM
/* Write the AAC bitstream */
bitStream = OpenBitStream(bufferSize, outputBuffer);
@@ -838,17 +885,11 @@
hEncoder->aacquantCfg.quality *= (1.0 - fix);
if (hEncoder->aacquantCfg.quality > 300)
hEncoder->aacquantCfg.quality = 300;
-#ifdef DRM
- /* since we have very low bit-rates in DRM, we have to decrease the
- bandwidth and also decrease the quality */
- if (hEncoder->aacquantCfg.quality < 10)
- hEncoder->aacquantCfg.quality = 10;
-#else
if (hEncoder->aacquantCfg.quality < 50)
hEncoder->aacquantCfg.quality = 50;
-#endif
}
}
+#endif
return frameBytes;
}
@@ -1070,6 +1111,9 @@
/*
$Log: frame.c,v $
+Revision 1.65 2004/07/18 09:34:24 corrados
+New bandwidth settings for DRM, improved quantization quality adaptation (almost constant bit-rate now)
+
Revision 1.64 2004/07/13 17:56:37 corrados
bug fix with new object type definitions