aaccoder: add intensity stereo coding support for the trellis quantizer

This commit extends the trellis quantizer (used by the default twoloop coder)
 to accept and correctly encode codebooks needed for intensity stereo and perceptual noise substitution.

Reviewed-by: Claudio Freire <klaussfreire@gmail.com>
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
pull/227/head
Rostislav Pehlivanov 10 years ago committed by Michael Niedermayer
parent ecbd111768
commit 305859c0d4
  1. 69
      libavcodec/aaccoder.c

@ -44,7 +44,10 @@
#define NOISE_LOW_LIMIT 4000 #define NOISE_LOW_LIMIT 4000
/** Total number of usable codebooks **/ /** Total number of usable codebooks **/
#define CB_TOT 13 #define CB_TOT 12
/** Total number of codebooks, including special ones **/
#define CB_TOT_ALL 15
/** bits needed to code codebook run value for long windows */ /** bits needed to code codebook run value for long windows */
static const uint8_t run_value_bits_long[64] = { static const uint8_t run_value_bits_long[64] = {
@ -64,9 +67,9 @@ static const uint8_t * const run_value_bits[2] = {
}; };
/** Map to convert values from BandCodingPath index to a codebook index **/ /** Map to convert values from BandCodingPath index to a codebook index **/
static const uint8_t aac_cb_out_map[CB_TOT] = {0,1,2,3,4,5,6,7,8,9,10,11,13}; static const uint8_t aac_cb_out_map[CB_TOT_ALL] = {0,1,2,3,4,5,6,7,8,9,10,11,13,14,15};
/** Inverse map to convert from codebooks to BandCodingPath indices **/ /** Inverse map to convert from codebooks to BandCodingPath indices **/
static const uint8_t aac_cb_in_map[CB_TOT+1] = {0,1,2,3,4,5,6,7,8,9,10,11,0,12}; static const uint8_t aac_cb_in_map[CB_TOT_ALL+1] = {0,1,2,3,4,5,6,7,8,9,10,11,0,12,13,14};
/** /**
* Quantize one coefficient. * Quantize one coefficient.
@ -118,7 +121,7 @@ static av_always_inline float quantize_and_encode_band_cost_template(
const float *scaled, int size, int scale_idx, const float *scaled, int size, int scale_idx,
int cb, const float lambda, const float uplim, int cb, const float lambda, const float uplim,
int *bits, int BT_ZERO, int BT_UNSIGNED, int *bits, int BT_ZERO, int BT_UNSIGNED,
int BT_PAIR, int BT_ESC, int BT_NOISE) int BT_PAIR, int BT_ESC, int BT_NOISE, int BT_STEREO)
{ {
const int q_idx = POW_SF2_ZERO - scale_idx + SCALE_ONE_POS - SCALE_DIV_512; const int q_idx = POW_SF2_ZERO - scale_idx + SCALE_ONE_POS - SCALE_DIV_512;
const float Q = ff_aac_pow2sf_tab [q_idx]; const float Q = ff_aac_pow2sf_tab [q_idx];
@ -131,14 +134,7 @@ static av_always_inline float quantize_and_encode_band_cost_template(
int resbits = 0; int resbits = 0;
int off; int off;
if (BT_ZERO) { if (BT_ZERO || BT_NOISE || BT_STEREO) {
for (i = 0; i < size; i++)
cost += in[i]*in[i];
if (bits)
*bits = 0;
return cost * lambda;
}
if (BT_NOISE) {
for (i = 0; i < size; i++) for (i = 0; i < size; i++)
cost += in[i]*in[i]; cost += in[i]*in[i];
if (bits) if (bits)
@ -231,26 +227,27 @@ static float quantize_and_encode_band_cost_NONE(struct AACEncContext *s, PutBitC
return 0.0f; return 0.0f;
} }
#define QUANTIZE_AND_ENCODE_BAND_COST_FUNC(NAME, BT_ZERO, BT_UNSIGNED, BT_PAIR, BT_ESC, BT_NOISE) \ #define QUANTIZE_AND_ENCODE_BAND_COST_FUNC(NAME, BT_ZERO, BT_UNSIGNED, BT_PAIR, BT_ESC, BT_NOISE, BT_STEREO) \
static float quantize_and_encode_band_cost_ ## NAME( \ static float quantize_and_encode_band_cost_ ## NAME( \
struct AACEncContext *s, \ struct AACEncContext *s, \
PutBitContext *pb, const float *in, \ PutBitContext *pb, const float *in, \
const float *scaled, int size, int scale_idx, \ const float *scaled, int size, int scale_idx, \
int cb, const float lambda, const float uplim, \ int cb, const float lambda, const float uplim, \
int *bits) { \ int *bits) { \
return quantize_and_encode_band_cost_template( \ return quantize_and_encode_band_cost_template( \
s, pb, in, scaled, size, scale_idx, \ s, pb, in, scaled, size, scale_idx, \
BT_ESC ? ESC_BT : cb, lambda, uplim, bits, \ BT_ESC ? ESC_BT : cb, lambda, uplim, bits, \
BT_ZERO, BT_UNSIGNED, BT_PAIR, BT_ESC, BT_NOISE); \ BT_ZERO, BT_UNSIGNED, BT_PAIR, BT_ESC, BT_NOISE, BT_STEREO); \
} }
QUANTIZE_AND_ENCODE_BAND_COST_FUNC(ZERO, 1, 0, 0, 0, 0) QUANTIZE_AND_ENCODE_BAND_COST_FUNC(ZERO, 1, 0, 0, 0, 0, 0)
QUANTIZE_AND_ENCODE_BAND_COST_FUNC(SQUAD, 0, 0, 0, 0, 0) QUANTIZE_AND_ENCODE_BAND_COST_FUNC(SQUAD, 0, 0, 0, 0, 0, 0)
QUANTIZE_AND_ENCODE_BAND_COST_FUNC(UQUAD, 0, 1, 0, 0, 0) QUANTIZE_AND_ENCODE_BAND_COST_FUNC(UQUAD, 0, 1, 0, 0, 0, 0)
QUANTIZE_AND_ENCODE_BAND_COST_FUNC(SPAIR, 0, 0, 1, 0, 0) QUANTIZE_AND_ENCODE_BAND_COST_FUNC(SPAIR, 0, 0, 1, 0, 0, 0)
QUANTIZE_AND_ENCODE_BAND_COST_FUNC(UPAIR, 0, 1, 1, 0, 0) QUANTIZE_AND_ENCODE_BAND_COST_FUNC(UPAIR, 0, 1, 1, 0, 0, 0)
QUANTIZE_AND_ENCODE_BAND_COST_FUNC(ESC, 0, 1, 1, 1, 0) QUANTIZE_AND_ENCODE_BAND_COST_FUNC(ESC, 0, 1, 1, 1, 0, 0)
QUANTIZE_AND_ENCODE_BAND_COST_FUNC(NOISE, 0, 0, 0, 0, 1) QUANTIZE_AND_ENCODE_BAND_COST_FUNC(NOISE, 0, 0, 0, 0, 1, 0)
QUANTIZE_AND_ENCODE_BAND_COST_FUNC(STEREO,0, 0, 0, 0, 0, 1)
static float (*const quantize_and_encode_band_cost_arr[])( static float (*const quantize_and_encode_band_cost_arr[])(
struct AACEncContext *s, struct AACEncContext *s,
@ -272,6 +269,8 @@ static float (*const quantize_and_encode_band_cost_arr[])(
quantize_and_encode_band_cost_ESC, quantize_and_encode_band_cost_ESC,
quantize_and_encode_band_cost_NONE, /* CB 12 doesn't exist */ quantize_and_encode_band_cost_NONE, /* CB 12 doesn't exist */
quantize_and_encode_band_cost_NOISE, quantize_and_encode_band_cost_NOISE,
quantize_and_encode_band_cost_STEREO,
quantize_and_encode_band_cost_STEREO,
}; };
#define quantize_and_encode_band_cost( \ #define quantize_and_encode_band_cost( \
@ -454,7 +453,7 @@ static void codebook_trellis_rate(AACEncContext *s, SingleChannelElement *sce,
abs_pow34_v(s->scoefs, sce->coeffs, 1024); abs_pow34_v(s->scoefs, sce->coeffs, 1024);
start = win*128; start = win*128;
for (cb = 0; cb < CB_TOT; cb++) { for (cb = 0; cb < CB_TOT_ALL; cb++) {
path[0][cb].cost = run_bits+4; path[0][cb].cost = run_bits+4;
path[0][cb].prev_idx = -1; path[0][cb].prev_idx = -1;
path[0][cb].run = 0; path[0][cb].run = 0;
@ -478,7 +477,7 @@ static void codebook_trellis_rate(AACEncContext *s, SingleChannelElement *sce,
} }
next_minbits = path[swb+1][0].cost; next_minbits = path[swb+1][0].cost;
next_mincb = 0; next_mincb = 0;
for (cb = 1; cb < CB_TOT; cb++) { for (cb = 1; cb < CB_TOT_ALL; cb++) {
path[swb+1][cb].cost = 61450; path[swb+1][cb].cost = 61450;
path[swb+1][cb].prev_idx = -1; path[swb+1][cb].prev_idx = -1;
path[swb+1][cb].run = 0; path[swb+1][cb].run = 0;
@ -495,10 +494,10 @@ static void codebook_trellis_rate(AACEncContext *s, SingleChannelElement *sce,
path[swb+1][cb].prev_idx = -1; path[swb+1][cb].prev_idx = -1;
path[swb+1][cb].run = 0; path[swb+1][cb].run = 0;
} }
for (cb = startcb; cb < CB_TOT; cb++) { for (cb = startcb; cb < CB_TOT_ALL; cb++) {
float cost_stay_here, cost_get_here; float cost_stay_here, cost_get_here;
float bits = 0.0f; float bits = 0.0f;
if (cb == 12 && sce->band_type[win*16+swb] != NOISE_BT) { if (cb >= 12 && sce->band_type[win*16+swb] != aac_cb_out_map[cb]) {
path[swb+1][cb].cost = 61450; path[swb+1][cb].cost = 61450;
path[swb+1][cb].prev_idx = -1; path[swb+1][cb].prev_idx = -1;
path[swb+1][cb].run = 0; path[swb+1][cb].run = 0;
@ -537,7 +536,7 @@ static void codebook_trellis_rate(AACEncContext *s, SingleChannelElement *sce,
//convert resulting path from backward-linked list //convert resulting path from backward-linked list
stack_len = 0; stack_len = 0;
idx = 0; idx = 0;
for (cb = 1; cb < CB_TOT; cb++) for (cb = 1; cb < CB_TOT_ALL; cb++)
if (path[max_sfb][cb].cost < path[max_sfb][idx].cost) if (path[max_sfb][cb].cost < path[max_sfb][idx].cost)
idx = cb; idx = cb;
ppos = max_sfb; ppos = max_sfb;

Loading…
Cancel
Save