mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2024-12-23 12:43:46 +02:00
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@gmx.at>
This commit is contained in:
parent
67fc32ac61
commit
7e0a284b9f
@ -78,7 +78,7 @@ typedef struct AC3Block {
|
|||||||
int16_t **band_psd; ///< psd per critical band
|
int16_t **band_psd; ///< psd per critical band
|
||||||
int16_t **mask; ///< masking curve
|
int16_t **mask; ///< masking curve
|
||||||
uint16_t **qmant; ///< quantized mantissas
|
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 new_rematrixing_strategy; ///< send new rematrixing flags in this block
|
||||||
uint8_t rematrixing_flags[4]; ///< rematrixing flags
|
uint8_t rematrixing_flags[4]; ///< rematrixing flags
|
||||||
} AC3Block;
|
} 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);
|
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);
|
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];
|
AC3Block *block = &s->blocks[blk];
|
||||||
uint8_t *exp = block->exp[ch];
|
uint8_t *exp = block->exp[ch];
|
||||||
int32_t *coef = block->fixed_coef[ch];
|
int32_t *coef = block->fixed_coef[ch];
|
||||||
int exp_shift = block->exp_shift[ch];
|
|
||||||
for (i = 0; i < AC3_MAX_COEFS; i++) {
|
for (i = 0; i < AC3_MAX_COEFS; i++) {
|
||||||
int e;
|
int e;
|
||||||
int v = abs(coef[i]);
|
int v = abs(coef[i]);
|
||||||
if (v == 0)
|
if (v == 0)
|
||||||
e = 24;
|
e = 24;
|
||||||
else {
|
else {
|
||||||
e = 23 - av_log2(v) + exp_shift;
|
e = 23 - av_log2(v);
|
||||||
if (e >= 24) {
|
if (e >= 24) {
|
||||||
e = 24;
|
e = 24;
|
||||||
coef[i] = 0;
|
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.
|
* 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,
|
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)
|
uint8_t *bap, uint16_t *qmant, int n)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
@ -1147,7 +1146,7 @@ static void quantize_mantissas_blk_ch(AC3EncodeContext *s, int32_t *fixed_coef,
|
|||||||
for (i = 0; i < n; i++) {
|
for (i = 0; i < n; i++) {
|
||||||
int v;
|
int v;
|
||||||
int c = fixed_coef[i];
|
int c = fixed_coef[i];
|
||||||
int e = exp[i] - exp_shift;
|
int e = exp[i];
|
||||||
int b = bap[i];
|
int b = bap[i];
|
||||||
switch (b) {
|
switch (b) {
|
||||||
case 0:
|
case 0:
|
||||||
@ -1243,7 +1242,7 @@ static void quantize_mantissas(AC3EncodeContext *s)
|
|||||||
s->qmant1_ptr = s->qmant2_ptr = s->qmant4_ptr = NULL;
|
s->qmant1_ptr = s->qmant2_ptr = s->qmant4_ptr = NULL;
|
||||||
|
|
||||||
for (ch = 0; ch < s->channels; ch++) {
|
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->exp[ch], block->bap[ch],
|
||||||
block->qmant[ch], s->nb_coefs[ch]);
|
block->qmant[ch], s->nb_coefs[ch]);
|
||||||
}
|
}
|
||||||
|
@ -294,29 +294,55 @@ 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.
|
* Normalize the input samples to use the maximum available precision.
|
||||||
* This assumes signed 16-bit input samples. Exponents are reduced by 9 to
|
* This assumes signed 16-bit input samples.
|
||||||
* match the 24-bit internal precision for MDCT coefficients.
|
|
||||||
*
|
*
|
||||||
* @return exponent shift
|
* @return coefficient shift
|
||||||
*/
|
*/
|
||||||
static int normalize_samples(AC3EncodeContext *s)
|
static int normalize_samples(AC3EncodeContext *s)
|
||||||
{
|
{
|
||||||
int v = 14 - log2_tab(s, s->windowed_samples, AC3_WINDOW_SIZE);
|
int v = 14 - log2_tab(s, s->windowed_samples, AC3_WINDOW_SIZE);
|
||||||
lshift_tab(s->windowed_samples, AC3_WINDOW_SIZE, v);
|
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)
|
static void scale_coefficients(AC3EncodeContext *s)
|
||||||
{
|
{
|
||||||
/* scaling/conversion is obviously not needed for the fixed-point encoder
|
int blk, ch;
|
||||||
since the coefficients are already fixed-point. */
|
|
||||||
return;
|
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]);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,2 +1,2 @@
|
|||||||
07bd593823ebd721b3a32ef298bdfc20 *./tests/data/acodec/ac3.rm
|
5f1255da35a4ed00a2e932887c9aef77 *./tests/data/acodec/ac3.rm
|
||||||
98751 ./tests/data/acodec/ac3.rm
|
98751 ./tests/data/acodec/ac3.rm
|
||||||
|
Loading…
Reference in New Issue
Block a user