[FFmpeg-cvslog] ac3enc: shift coefficients to 24-bit following MDCT rather than using an exponent offset .
Justin Ruggles
git
Tue Mar 8 20:01:41 CET 2011
ffmpeg | branch: master | Justin Ruggles <justin.ruggles at gmail.com> | Tue Mar 8 13:18:56 2011 -0500| [7e0a284b9f1967d46603711e85e0be01e084eadf] | committer: Michael Niedermayer
ac3enc: shift coefficients to 24-bit following MDCT rather than using an exponent offset.
This makes channel coupling more accurate, increasing quality for stereo
content. It also simplifies exponent extraction and mantissa quantization
by no longer needing to apply an offset to the exponents.
Signed-off-by: Michael Niedermayer <michaelni at gmx.at>
> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=7e0a284b9f1967d46603711e85e0be01e084eadf
---
libavcodec/ac3enc.c | 13 ++++++-------
libavcodec/ac3enc_fixed.c | 42 ++++++++++++++++++++++++++++++++++--------
tests/ref/acodec/ac3_fixed | 2 +-
3 files changed, 41 insertions(+), 16 deletions(-)
diff --git a/libavcodec/ac3enc.c b/libavcodec/ac3enc.c
index e792eaf..4fc8106 100644
--- a/libavcodec/ac3enc.c
+++ b/libavcodec/ac3enc.c
@@ -78,7 +78,7 @@ typedef struct AC3Block {
int16_t **band_psd; ///< psd per critical band
int16_t **mask; ///< masking curve
uint16_t **qmant; ///< quantized mantissas
- int8_t exp_shift[AC3_MAX_CHANNELS]; ///< exponent shift values
+ int8_t coeff_shift[AC3_MAX_CHANNELS]; ///< fixed-point coefficient shift values
uint8_t new_rematrixing_strategy; ///< send new rematrixing flags in this block
uint8_t rematrixing_flags[4]; ///< rematrixing flags
} AC3Block;
@@ -269,7 +269,7 @@ static void apply_mdct(AC3EncodeContext *s)
apply_window(&s->dsp, s->windowed_samples, input_samples, s->mdct.window, AC3_WINDOW_SIZE);
- block->exp_shift[ch] = normalize_samples(s);
+ block->coeff_shift[ch] = normalize_samples(s);
mdct512(&s->mdct, block->mdct_coef[ch], s->windowed_samples);
}
@@ -416,14 +416,13 @@ static void extract_exponents(AC3EncodeContext *s)
AC3Block *block = &s->blocks[blk];
uint8_t *exp = block->exp[ch];
int32_t *coef = block->fixed_coef[ch];
- int exp_shift = block->exp_shift[ch];
for (i = 0; i < AC3_MAX_COEFS; i++) {
int e;
int v = abs(coef[i]);
if (v == 0)
e = 24;
else {
- e = 23 - av_log2(v) + exp_shift;
+ e = 23 - av_log2(v);
if (e >= 24) {
e = 24;
coef[i] = 0;
@@ -1139,7 +1138,7 @@ static inline int asym_quant(int c, int e, int qbits)
* Quantize a set of mantissas for a single channel in a single block.
*/
static void quantize_mantissas_blk_ch(AC3EncodeContext *s, int32_t *fixed_coef,
- int8_t exp_shift, uint8_t *exp,
+ uint8_t *exp,
uint8_t *bap, uint16_t *qmant, int n)
{
int i;
@@ -1147,7 +1146,7 @@ static void quantize_mantissas_blk_ch(AC3EncodeContext *s, int32_t *fixed_coef,
for (i = 0; i < n; i++) {
int v;
int c = fixed_coef[i];
- int e = exp[i] - exp_shift;
+ int e = exp[i];
int b = bap[i];
switch (b) {
case 0:
@@ -1243,7 +1242,7 @@ static void quantize_mantissas(AC3EncodeContext *s)
s->qmant1_ptr = s->qmant2_ptr = s->qmant4_ptr = NULL;
for (ch = 0; ch < s->channels; ch++) {
- quantize_mantissas_blk_ch(s, block->fixed_coef[ch], block->exp_shift[ch],
+ quantize_mantissas_blk_ch(s, block->fixed_coef[ch],
block->exp[ch], block->bap[ch],
block->qmant[ch], s->nb_coefs[ch]);
}
diff --git a/libavcodec/ac3enc_fixed.c b/libavcodec/ac3enc_fixed.c
index 3de00ee..e5853a3 100644
--- a/libavcodec/ac3enc_fixed.c
+++ b/libavcodec/ac3enc_fixed.c
@@ -295,28 +295,54 @@ static void lshift_tab(int16_t *tab, int n, unsigned int lshift)
/**
+ * Shift each value in an array by a specified amount.
+ * @param src input array
+ * @param n number of values in the array
+ * @param shift shift amount (negative=right, positive=left)
+ */
+static void shift_int32(int32_t *src, int n, int shift)
+{
+ int i;
+
+ if (shift > 0) {
+ for (i = 0; i < n; i++)
+ src[i] <<= shift;
+ } else if (shift < 0) {
+ shift = -shift;
+ for (i = 0; i < n; i++)
+ src[i] >>= shift;
+ }
+}
+
+
+/**
* Normalize the input samples to use the maximum available precision.
- * This assumes signed 16-bit input samples. Exponents are reduced by 9 to
- * match the 24-bit internal precision for MDCT coefficients.
+ * This assumes signed 16-bit input samples.
*
- * @return exponent shift
+ * @return coefficient shift
*/
static int normalize_samples(AC3EncodeContext *s)
{
int v = 14 - log2_tab(s, s->windowed_samples, AC3_WINDOW_SIZE);
lshift_tab(s->windowed_samples, AC3_WINDOW_SIZE, v);
- return v - 9;
+ return 9 - v;
}
/**
- * Scale MDCT coefficients from float to fixed-point.
+ * Scale MDCT coefficients to 24-bit fixed-point.
*/
static void scale_coefficients(AC3EncodeContext *s)
{
- /* scaling/conversion is obviously not needed for the fixed-point encoder
- since the coefficients are already fixed-point. */
- return;
+ int blk, ch;
+
+ for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) {
+ AC3Block *block = &s->blocks[blk];
+ for (ch = 0; ch < s->channels; ch++) {
+ shift_int32(block->mdct_coef[ch], AC3_MAX_COEFS,
+ block->coeff_shift[ch]);
+ }
+ }
}
diff --git a/tests/ref/acodec/ac3_fixed b/tests/ref/acodec/ac3_fixed
index f32443d..89e0be5 100644
--- a/tests/ref/acodec/ac3_fixed
+++ b/tests/ref/acodec/ac3_fixed
@@ -1,2 +1,2 @@
-07bd593823ebd721b3a32ef298bdfc20 *./tests/data/acodec/ac3.rm
+5f1255da35a4ed00a2e932887c9aef77 *./tests/data/acodec/ac3.rm
98751 ./tests/data/acodec/ac3.rm
More information about the ffmpeg-cvslog
mailing list