|
|
|
@@ -52,12 +52,6 @@ |
|
|
|
/** Maximum number of exponent groups. +1 for separate DC exponent. */ |
|
|
|
#define AC3_MAX_EXP_GROUPS 85 |
|
|
|
|
|
|
|
/* stereo rematrixing algorithms */ |
|
|
|
#define AC3_REMATRIXING_IS_STATIC 0x1 |
|
|
|
#define AC3_REMATRIXING_SUMS 0 |
|
|
|
#define AC3_REMATRIXING_NONE 1 |
|
|
|
#define AC3_REMATRIXING_ALWAYS 3 |
|
|
|
|
|
|
|
#if CONFIG_AC3ENC_FLOAT |
|
|
|
#define MAC_COEF(d,a,b) ((d)+=(a)*(b)) |
|
|
|
typedef float SampleType; |
|
|
|
@@ -137,10 +131,10 @@ typedef struct AC3EncodeContext { |
|
|
|
int loro_surround_mix_level; ///< Lo/Ro surround mix level code |
|
|
|
|
|
|
|
int cutoff; ///< user-specified cutoff frequency, in Hz |
|
|
|
int bandwidth_code[AC3_MAX_CHANNELS]; ///< bandwidth code (0 to 60) (chbwcod) |
|
|
|
int bandwidth_code; ///< bandwidth code (0 to 60) (chbwcod) |
|
|
|
int nb_coefs[AC3_MAX_CHANNELS]; |
|
|
|
|
|
|
|
int rematrixing; ///< determines how rematrixing strategy is calculated |
|
|
|
int rematrixing_enabled; ///< stereo rematrixing enabled |
|
|
|
int num_rematrixing_bands; ///< number of rematrixing bands |
|
|
|
|
|
|
|
/* bitrate allocation control */ |
|
|
|
@@ -240,6 +234,8 @@ const AVOption ff_ac3_options[] = { |
|
|
|
{"ad_conv_type", "A/D Converter Type", OFFSET(ad_converter_type), FF_OPT_TYPE_INT, {.dbl = -1 }, -1, 1, AC3ENC_PARAM, "ad_conv_type"}, |
|
|
|
{"standard", "Standard (default)", 0, FF_OPT_TYPE_CONST, {.dbl = 0 }, INT_MIN, INT_MAX, AC3ENC_PARAM, "ad_conv_type"}, |
|
|
|
{"hdcd", "HDCD", 0, FF_OPT_TYPE_CONST, {.dbl = 1 }, INT_MIN, INT_MAX, AC3ENC_PARAM, "ad_conv_type"}, |
|
|
|
/* Other Encoding Options */ |
|
|
|
{"stereo_rematrixing", "Stereo Rematrixing", OFFSET(stereo_rematrixing), FF_OPT_TYPE_INT, {.dbl = 1 }, 0, 1, AC3ENC_PARAM}, |
|
|
|
{NULL} |
|
|
|
}; |
|
|
|
#endif |
|
|
|
@@ -404,28 +400,6 @@ static void apply_mdct(AC3EncodeContext *s) |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
* Initialize stereo rematrixing. |
|
|
|
* If the strategy does not change for each frame, set the rematrixing flags. |
|
|
|
*/ |
|
|
|
static void rematrixing_init(AC3EncodeContext *s) |
|
|
|
{ |
|
|
|
if (s->channel_mode == AC3_CHMODE_STEREO) |
|
|
|
s->rematrixing = AC3_REMATRIXING_SUMS; |
|
|
|
else |
|
|
|
s->rematrixing = AC3_REMATRIXING_NONE; |
|
|
|
/* NOTE: AC3_REMATRIXING_ALWAYS might be used in |
|
|
|
the future in conjunction with channel coupling. */ |
|
|
|
|
|
|
|
if (s->rematrixing & AC3_REMATRIXING_IS_STATIC) { |
|
|
|
int flag = (s->rematrixing == AC3_REMATRIXING_ALWAYS); |
|
|
|
s->blocks[0].new_rematrixing_strategy = 1; |
|
|
|
memset(s->blocks[0].rematrixing_flags, flag, |
|
|
|
sizeof(s->blocks[0].rematrixing_flags)); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
* Determine rematrixing flags for each block and band. |
|
|
|
*/ |
|
|
|
@@ -435,16 +409,18 @@ static void compute_rematrixing_strategy(AC3EncodeContext *s) |
|
|
|
int blk, bnd, i; |
|
|
|
AC3Block *block, *block0; |
|
|
|
|
|
|
|
s->num_rematrixing_bands = 4; |
|
|
|
|
|
|
|
if (s->rematrixing & AC3_REMATRIXING_IS_STATIC) |
|
|
|
if (s->channel_mode != AC3_CHMODE_STEREO) |
|
|
|
return; |
|
|
|
|
|
|
|
s->num_rematrixing_bands = 4; |
|
|
|
|
|
|
|
nb_coefs = FFMIN(s->nb_coefs[0], s->nb_coefs[1]); |
|
|
|
|
|
|
|
for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) { |
|
|
|
block = &s->blocks[blk]; |
|
|
|
block->new_rematrixing_strategy = !blk; |
|
|
|
if (!s->rematrixing_enabled) |
|
|
|
continue; |
|
|
|
for (bnd = 0; bnd < s->num_rematrixing_bands; bnd++) { |
|
|
|
/* calculate calculate sum of squared coeffs for one band in one block */ |
|
|
|
int start = ff_ac3_rematrix_band_tab[bnd]; |
|
|
|
@@ -488,7 +464,7 @@ static void apply_rematrixing(AC3EncodeContext *s) |
|
|
|
int start, end; |
|
|
|
uint8_t *flags; |
|
|
|
|
|
|
|
if (s->rematrixing == AC3_REMATRIXING_NONE) |
|
|
|
if (!s->rematrixing_enabled) |
|
|
|
return; |
|
|
|
|
|
|
|
nb_coefs = FFMIN(s->nb_coefs[0], s->nb_coefs[1]); |
|
|
|
@@ -518,11 +494,13 @@ static void apply_rematrixing(AC3EncodeContext *s) |
|
|
|
*/ |
|
|
|
static av_cold void exponent_init(AC3EncodeContext *s) |
|
|
|
{ |
|
|
|
int i; |
|
|
|
for (i = 73; i < 256; i++) { |
|
|
|
exponent_group_tab[0][i] = (i - 1) / 3; |
|
|
|
exponent_group_tab[1][i] = (i + 2) / 6; |
|
|
|
exponent_group_tab[2][i] = (i + 8) / 12; |
|
|
|
int expstr, i, grpsize; |
|
|
|
|
|
|
|
for (expstr = EXP_D15-1; expstr <= EXP_D45-1; expstr++) { |
|
|
|
grpsize = 3 << expstr; |
|
|
|
for (i = 73; i < 256; i++) { |
|
|
|
exponent_group_tab[expstr][i] = (i + grpsize - 4) / grpsize; |
|
|
|
} |
|
|
|
} |
|
|
|
/* LFE */ |
|
|
|
exponent_group_tab[0][7] = 2; |
|
|
|
@@ -555,56 +533,47 @@ static void extract_exponents(AC3EncodeContext *s) |
|
|
|
#define EXP_DIFF_THRESHOLD 500 |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
* Calculate exponent strategies for all blocks in a single channel. |
|
|
|
*/ |
|
|
|
static void compute_exp_strategy_ch(AC3EncodeContext *s, uint8_t *exp_strategy, |
|
|
|
uint8_t *exp) |
|
|
|
{ |
|
|
|
int blk, blk1; |
|
|
|
int exp_diff; |
|
|
|
|
|
|
|
/* estimate if the exponent variation & decide if they should be |
|
|
|
reused in the next frame */ |
|
|
|
exp_strategy[0] = EXP_NEW; |
|
|
|
exp += AC3_MAX_COEFS; |
|
|
|
for (blk = 1; blk < AC3_MAX_BLOCKS; blk++) { |
|
|
|
exp_diff = s->dsp.sad[0](NULL, exp, exp - AC3_MAX_COEFS, 16, 16); |
|
|
|
if (exp_diff > EXP_DIFF_THRESHOLD) |
|
|
|
exp_strategy[blk] = EXP_NEW; |
|
|
|
else |
|
|
|
exp_strategy[blk] = EXP_REUSE; |
|
|
|
exp += AC3_MAX_COEFS; |
|
|
|
} |
|
|
|
|
|
|
|
/* now select the encoding strategy type : if exponents are often |
|
|
|
recoded, we use a coarse encoding */ |
|
|
|
blk = 0; |
|
|
|
while (blk < AC3_MAX_BLOCKS) { |
|
|
|
blk1 = blk + 1; |
|
|
|
while (blk1 < AC3_MAX_BLOCKS && exp_strategy[blk1] == EXP_REUSE) |
|
|
|
blk1++; |
|
|
|
switch (blk1 - blk) { |
|
|
|
case 1: exp_strategy[blk] = EXP_D45; break; |
|
|
|
case 2: |
|
|
|
case 3: exp_strategy[blk] = EXP_D25; break; |
|
|
|
default: exp_strategy[blk] = EXP_D15; break; |
|
|
|
} |
|
|
|
blk = blk1; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
* Calculate exponent strategies for all channels. |
|
|
|
* Array arrangement is reversed to simplify the per-channel calculation. |
|
|
|
*/ |
|
|
|
static void compute_exp_strategy(AC3EncodeContext *s) |
|
|
|
{ |
|
|
|
int ch, blk; |
|
|
|
int ch, blk, blk1; |
|
|
|
|
|
|
|
for (ch = 0; ch < s->fbw_channels; ch++) { |
|
|
|
compute_exp_strategy_ch(s, s->exp_strategy[ch], s->blocks[0].exp[ch]); |
|
|
|
uint8_t *exp_strategy = s->exp_strategy[ch]; |
|
|
|
uint8_t *exp = s->blocks[0].exp[ch]; |
|
|
|
int exp_diff; |
|
|
|
|
|
|
|
/* estimate if the exponent variation & decide if they should be |
|
|
|
reused in the next frame */ |
|
|
|
exp_strategy[0] = EXP_NEW; |
|
|
|
exp += AC3_MAX_COEFS; |
|
|
|
for (blk = 1; blk < AC3_MAX_BLOCKS; blk++) { |
|
|
|
exp_diff = s->dsp.sad[0](NULL, exp, exp - AC3_MAX_COEFS, 16, 16); |
|
|
|
if (exp_diff > EXP_DIFF_THRESHOLD) |
|
|
|
exp_strategy[blk] = EXP_NEW; |
|
|
|
else |
|
|
|
exp_strategy[blk] = EXP_REUSE; |
|
|
|
exp += AC3_MAX_COEFS; |
|
|
|
} |
|
|
|
|
|
|
|
/* now select the encoding strategy type : if exponents are often |
|
|
|
recoded, we use a coarse encoding */ |
|
|
|
blk = 0; |
|
|
|
while (blk < AC3_MAX_BLOCKS) { |
|
|
|
blk1 = blk + 1; |
|
|
|
while (blk1 < AC3_MAX_BLOCKS && exp_strategy[blk1] == EXP_REUSE) |
|
|
|
blk1++; |
|
|
|
switch (blk1 - blk) { |
|
|
|
case 1: exp_strategy[blk] = EXP_D45; break; |
|
|
|
case 2: |
|
|
|
case 3: exp_strategy[blk] = EXP_D25; break; |
|
|
|
default: exp_strategy[blk] = EXP_D15; break; |
|
|
|
} |
|
|
|
blk = blk1; |
|
|
|
} |
|
|
|
} |
|
|
|
if (s->lfe_on) { |
|
|
|
ch = s->lfe_channel; |
|
|
|
@@ -1005,7 +974,8 @@ static int bit_alloc(AC3EncodeContext *s, int snr_offset) |
|
|
|
reset_block_bap(s); |
|
|
|
mantissa_bits = 0; |
|
|
|
for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) { |
|
|
|
AC3Block *block; |
|
|
|
AC3Block *block = &s->blocks[blk]; |
|
|
|
AC3Block *ref_block; |
|
|
|
// initialize grouped mantissa counts. these are set so that they are |
|
|
|
// padded to the next whole group size when bits are counted in |
|
|
|
// compute_mantissa_size_final |
|
|
|
@@ -1017,14 +987,17 @@ static int bit_alloc(AC3EncodeContext *s, int snr_offset) |
|
|
|
blocks within a frame are the exponent values. We can take |
|
|
|
advantage of that by reusing the bit allocation pointers |
|
|
|
whenever we reuse exponents. */ |
|
|
|
block = s->blocks[blk].exp_ref_block[ch]; |
|
|
|
ref_block = block->exp_ref_block[ch]; |
|
|
|
if (s->exp_strategy[ch][blk] != EXP_REUSE) { |
|
|
|
s->ac3dsp.bit_alloc_calc_bap(block->mask[ch], block->psd[ch], 0, |
|
|
|
s->nb_coefs[ch], snr_offset, |
|
|
|
s->bit_alloc.floor, ff_ac3_bap_tab, |
|
|
|
block->bap[ch]); |
|
|
|
s->ac3dsp.bit_alloc_calc_bap(ref_block->mask[ch], |
|
|
|
ref_block->psd[ch], 0, |
|
|
|
s->nb_coefs[ch], snr_offset, |
|
|
|
s->bit_alloc.floor, ff_ac3_bap_tab, |
|
|
|
ref_block->bap[ch]); |
|
|
|
} |
|
|
|
mantissa_bits += s->ac3dsp.compute_mantissa_size(mant_cnt, block->bap[ch], s->nb_coefs[ch]); |
|
|
|
mantissa_bits += s->ac3dsp.compute_mantissa_size(mant_cnt, |
|
|
|
ref_block->bap[ch], |
|
|
|
s->nb_coefs[ch]); |
|
|
|
} |
|
|
|
mantissa_bits += compute_mantissa_size_final(mant_cnt); |
|
|
|
} |
|
|
|
@@ -1043,7 +1016,8 @@ static int cbr_bit_allocation(AC3EncodeContext *s) |
|
|
|
int snr_offset, snr_incr; |
|
|
|
|
|
|
|
bits_left = 8 * s->frame_size - (s->frame_bits + s->exponent_bits); |
|
|
|
av_assert2(bits_left >= 0); |
|
|
|
if (bits_left < 0) |
|
|
|
return AVERROR(EINVAL); |
|
|
|
|
|
|
|
snr_offset = s->coarse_snr_offset << 4; |
|
|
|
|
|
|
|
@@ -1121,27 +1095,6 @@ static int downgrade_exponents(AC3EncodeContext *s) |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
* Reduce the bandwidth to reduce the number of bits used for a given SNR offset. |
|
|
|
* This is a second fallback for when bit allocation still fails after exponents |
|
|
|
* have been downgraded. |
|
|
|
* @return non-zero if bandwidth reduction was unsuccessful |
|
|
|
*/ |
|
|
|
static int reduce_bandwidth(AC3EncodeContext *s, int min_bw_code) |
|
|
|
{ |
|
|
|
int ch; |
|
|
|
|
|
|
|
if (s->bandwidth_code[0] > min_bw_code) { |
|
|
|
for (ch = 0; ch < s->fbw_channels; ch++) { |
|
|
|
s->bandwidth_code[ch]--; |
|
|
|
s->nb_coefs[ch] = s->bandwidth_code[ch] * 3 + 73; |
|
|
|
} |
|
|
|
return 0; |
|
|
|
} |
|
|
|
return -1; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
* Perform bit allocation search. |
|
|
|
* Finds the SNR offset value that maximizes quality and fits in the specified |
|
|
|
@@ -1167,15 +1120,6 @@ static int compute_bit_allocation(AC3EncodeContext *s) |
|
|
|
continue; |
|
|
|
} |
|
|
|
|
|
|
|
/* fallback 2: reduce bandwidth */ |
|
|
|
/* only do this if the user has not specified a specific cutoff |
|
|
|
frequency */ |
|
|
|
if (!s->cutoff && !reduce_bandwidth(s, 0)) { |
|
|
|
process_exponents(s); |
|
|
|
ret = compute_bit_allocation(s); |
|
|
|
continue; |
|
|
|
} |
|
|
|
|
|
|
|
/* fallbacks were not enough... */ |
|
|
|
break; |
|
|
|
} |
|
|
|
@@ -1436,7 +1380,7 @@ static void output_audio_block(AC3EncodeContext *s, int blk) |
|
|
|
/* bandwidth */ |
|
|
|
for (ch = 0; ch < s->fbw_channels; ch++) { |
|
|
|
if (s->exp_strategy[ch][blk] != EXP_REUSE) |
|
|
|
put_bits(&s->pb, 6, s->bandwidth_code[ch]); |
|
|
|
put_bits(&s->pb, 6, s->bandwidth_code); |
|
|
|
} |
|
|
|
|
|
|
|
/* exponents */ |
|
|
|
@@ -2062,6 +2006,9 @@ static av_cold int validate_options(AVCodecContext *avctx, AC3EncodeContext *s) |
|
|
|
if (ret) |
|
|
|
return ret; |
|
|
|
|
|
|
|
s->rematrixing_enabled = s->options.stereo_rematrixing && |
|
|
|
(s->channel_mode == AC3_CHMODE_STEREO); |
|
|
|
|
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
@@ -2073,22 +2020,21 @@ static av_cold int validate_options(AVCodecContext *avctx, AC3EncodeContext *s) |
|
|
|
*/ |
|
|
|
static av_cold void set_bandwidth(AC3EncodeContext *s) |
|
|
|
{ |
|
|
|
int ch, bw_code; |
|
|
|
int ch; |
|
|
|
|
|
|
|
if (s->cutoff) { |
|
|
|
/* calculate bandwidth based on user-specified cutoff frequency */ |
|
|
|
int fbw_coeffs; |
|
|
|
fbw_coeffs = s->cutoff * 2 * AC3_MAX_COEFS / s->sample_rate; |
|
|
|
bw_code = av_clip((fbw_coeffs - 73) / 3, 0, 60); |
|
|
|
s->bandwidth_code = av_clip((fbw_coeffs - 73) / 3, 0, 60); |
|
|
|
} else { |
|
|
|
/* use default bandwidth setting */ |
|
|
|
bw_code = ac3_bandwidth_tab[s->fbw_channels-1][s->bit_alloc.sr_code][s->frame_size_code/2]; |
|
|
|
s->bandwidth_code = ac3_bandwidth_tab[s->fbw_channels-1][s->bit_alloc.sr_code][s->frame_size_code/2]; |
|
|
|
} |
|
|
|
|
|
|
|
/* set number of coefficients for each channel */ |
|
|
|
for (ch = 0; ch < s->fbw_channels; ch++) { |
|
|
|
s->bandwidth_code[ch] = bw_code; |
|
|
|
s->nb_coefs[ch] = bw_code * 3 + 73; |
|
|
|
s->nb_coefs[ch] = s->bandwidth_code * 3 + 73; |
|
|
|
} |
|
|
|
if (s->lfe_on) |
|
|
|
s->nb_coefs[s->lfe_channel] = 7; /* LFE channel always has 7 coefs */ |
|
|
|
@@ -2220,8 +2166,6 @@ static av_cold int ac3_encode_init(AVCodecContext *avctx) |
|
|
|
|
|
|
|
set_bandwidth(s); |
|
|
|
|
|
|
|
rematrixing_init(s); |
|
|
|
|
|
|
|
exponent_init(s); |
|
|
|
|
|
|
|
bit_alloc_init(s); |
|
|
|
|