Commit be7bd626 authored by Justin Ruggles's avatar Justin Ruggles

eac3enc: use different numbers of blocks per frame to allow higher bitrates

parent 4555874a
...@@ -186,7 +186,7 @@ void ff_ac3_adjust_frame_size(AC3EncodeContext *s) ...@@ -186,7 +186,7 @@ void ff_ac3_adjust_frame_size(AC3EncodeContext *s)
s->frame_size = s->frame_size_min + s->frame_size = s->frame_size_min +
2 * (s->bits_written * s->sample_rate < s->samples_written * s->bit_rate); 2 * (s->bits_written * s->sample_rate < s->samples_written * s->bit_rate);
s->bits_written += s->frame_size * 8; s->bits_written += s->frame_size * 8;
s->samples_written += AC3_FRAME_SIZE; s->samples_written += AC3_BLOCK_SIZE * s->num_blocks;
} }
...@@ -198,7 +198,7 @@ void ff_ac3_compute_coupling_strategy(AC3EncodeContext *s) ...@@ -198,7 +198,7 @@ void ff_ac3_compute_coupling_strategy(AC3EncodeContext *s)
/* set coupling use flags for each block/channel */ /* set coupling use flags for each block/channel */
/* TODO: turn coupling on/off and adjust start band based on bit usage */ /* TODO: turn coupling on/off and adjust start band based on bit usage */
for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) { for (blk = 0; blk < s->num_blocks; blk++) {
AC3Block *block = &s->blocks[blk]; AC3Block *block = &s->blocks[blk];
for (ch = 1; ch <= s->fbw_channels; ch++) for (ch = 1; ch <= s->fbw_channels; ch++)
block->channel_in_cpl[ch] = s->cpl_on; block->channel_in_cpl[ch] = s->cpl_on;
...@@ -208,7 +208,7 @@ void ff_ac3_compute_coupling_strategy(AC3EncodeContext *s) ...@@ -208,7 +208,7 @@ void ff_ac3_compute_coupling_strategy(AC3EncodeContext *s)
enabled for that block */ enabled for that block */
got_cpl_snr = 0; got_cpl_snr = 0;
num_cpl_blocks = 0; num_cpl_blocks = 0;
for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) { for (blk = 0; blk < s->num_blocks; blk++) {
AC3Block *block = &s->blocks[blk]; AC3Block *block = &s->blocks[blk];
block->num_cpl_channels = 0; block->num_cpl_channels = 0;
for (ch = 1; ch <= s->fbw_channels; ch++) for (ch = 1; ch <= s->fbw_channels; ch++)
...@@ -244,7 +244,7 @@ void ff_ac3_compute_coupling_strategy(AC3EncodeContext *s) ...@@ -244,7 +244,7 @@ void ff_ac3_compute_coupling_strategy(AC3EncodeContext *s)
s->cpl_on = 0; s->cpl_on = 0;
/* set bandwidth for each channel */ /* set bandwidth for each channel */
for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) { for (blk = 0; blk < s->num_blocks; blk++) {
AC3Block *block = &s->blocks[blk]; AC3Block *block = &s->blocks[blk];
for (ch = 1; ch <= s->fbw_channels; ch++) { for (ch = 1; ch <= s->fbw_channels; ch++) {
if (block->channel_in_cpl[ch]) if (block->channel_in_cpl[ch])
...@@ -269,7 +269,7 @@ void ff_ac3_apply_rematrixing(AC3EncodeContext *s) ...@@ -269,7 +269,7 @@ void ff_ac3_apply_rematrixing(AC3EncodeContext *s)
if (!s->rematrixing_enabled) if (!s->rematrixing_enabled)
return; return;
for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) { for (blk = 0; blk < s->num_blocks; blk++) {
AC3Block *block = &s->blocks[blk]; AC3Block *block = &s->blocks[blk];
if (block->new_rematrixing_strategy) if (block->new_rematrixing_strategy)
flags = block->rematrixing_flags; flags = block->rematrixing_flags;
...@@ -318,7 +318,7 @@ static av_cold void exponent_init(AC3EncodeContext *s) ...@@ -318,7 +318,7 @@ static av_cold void exponent_init(AC3EncodeContext *s)
static void extract_exponents(AC3EncodeContext *s) static void extract_exponents(AC3EncodeContext *s)
{ {
int ch = !s->cpl_on; int ch = !s->cpl_on;
int chan_size = AC3_MAX_COEFS * AC3_MAX_BLOCKS * (s->channels - ch + 1); int chan_size = AC3_MAX_COEFS * s->num_blocks * (s->channels - ch + 1);
AC3Block *block = &s->blocks[0]; AC3Block *block = &s->blocks[0];
s->ac3dsp.extract_exponents(block->exp[ch], block->fixed_coef[ch], chan_size); s->ac3dsp.extract_exponents(block->exp[ch], block->fixed_coef[ch], chan_size);
...@@ -331,6 +331,15 @@ static void extract_exponents(AC3EncodeContext *s) ...@@ -331,6 +331,15 @@ static void extract_exponents(AC3EncodeContext *s)
*/ */
#define EXP_DIFF_THRESHOLD 500 #define EXP_DIFF_THRESHOLD 500
/**
* Table used to select exponent strategy based on exponent reuse block interval.
*/
static const uint8_t exp_strategy_reuse_tab[4][6] = {
{ EXP_D15, EXP_D15, EXP_D15, EXP_D15, EXP_D15, EXP_D15 },
{ EXP_D15, EXP_D15, EXP_D15, EXP_D15, EXP_D15, EXP_D15 },
{ EXP_D25, EXP_D25, EXP_D15, EXP_D15, EXP_D15, EXP_D15 },
{ EXP_D45, EXP_D25, EXP_D25, EXP_D15, EXP_D15, EXP_D15 }
};
/** /**
* Calculate exponent strategies for all channels. * Calculate exponent strategies for all channels.
...@@ -349,7 +358,7 @@ static void compute_exp_strategy(AC3EncodeContext *s) ...@@ -349,7 +358,7 @@ static void compute_exp_strategy(AC3EncodeContext *s)
reused in the next frame */ reused in the next frame */
exp_strategy[0] = EXP_NEW; exp_strategy[0] = EXP_NEW;
exp += AC3_MAX_COEFS; exp += AC3_MAX_COEFS;
for (blk = 1; blk < AC3_MAX_BLOCKS; blk++, exp += AC3_MAX_COEFS) { for (blk = 1; blk < s->num_blocks; blk++, exp += AC3_MAX_COEFS) {
if (ch == CPL_CH) { if (ch == CPL_CH) {
if (!s->blocks[blk-1].cpl_in_use) { if (!s->blocks[blk-1].cpl_in_use) {
exp_strategy[blk] = EXP_NEW; exp_strategy[blk] = EXP_NEW;
...@@ -373,23 +382,18 @@ static void compute_exp_strategy(AC3EncodeContext *s) ...@@ -373,23 +382,18 @@ static void compute_exp_strategy(AC3EncodeContext *s)
/* now select the encoding strategy type : if exponents are often /* now select the encoding strategy type : if exponents are often
recoded, we use a coarse encoding */ recoded, we use a coarse encoding */
blk = 0; blk = 0;
while (blk < AC3_MAX_BLOCKS) { while (blk < s->num_blocks) {
blk1 = blk + 1; blk1 = blk + 1;
while (blk1 < AC3_MAX_BLOCKS && exp_strategy[blk1] == EXP_REUSE) while (blk1 < s->num_blocks && exp_strategy[blk1] == EXP_REUSE)
blk1++; blk1++;
switch (blk1 - blk) { exp_strategy[blk] = exp_strategy_reuse_tab[s->num_blks_code][blk1-blk-1];
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; blk = blk1;
} }
} }
if (s->lfe_on) { if (s->lfe_on) {
ch = s->lfe_channel; ch = s->lfe_channel;
s->exp_strategy[ch][0] = EXP_D15; s->exp_strategy[ch][0] = EXP_D15;
for (blk = 1; blk < AC3_MAX_BLOCKS; blk++) for (blk = 1; blk < s->num_blocks; blk++)
s->exp_strategy[ch][blk] = EXP_REUSE; s->exp_strategy[ch][blk] = EXP_REUSE;
} }
...@@ -487,7 +491,7 @@ static void encode_exponents(AC3EncodeContext *s) ...@@ -487,7 +491,7 @@ static void encode_exponents(AC3EncodeContext *s)
cpl = (ch == CPL_CH); cpl = (ch == CPL_CH);
blk = 0; blk = 0;
while (blk < AC3_MAX_BLOCKS) { while (blk < s->num_blocks) {
AC3Block *block = &s->blocks[blk]; AC3Block *block = &s->blocks[blk];
if (cpl && !block->cpl_in_use) { if (cpl && !block->cpl_in_use) {
exp += AC3_MAX_COEFS; exp += AC3_MAX_COEFS;
...@@ -500,7 +504,7 @@ static void encode_exponents(AC3EncodeContext *s) ...@@ -500,7 +504,7 @@ static void encode_exponents(AC3EncodeContext *s)
/* count the number of EXP_REUSE blocks after the current block /* count the number of EXP_REUSE blocks after the current block
and set exponent reference block numbers */ and set exponent reference block numbers */
s->exp_ref_block[ch][blk] = blk; s->exp_ref_block[ch][blk] = blk;
while (blk1 < AC3_MAX_BLOCKS && exp_strategy[blk1] == EXP_REUSE) { while (blk1 < s->num_blocks && exp_strategy[blk1] == EXP_REUSE) {
s->exp_ref_block[ch][blk1] = blk; s->exp_ref_block[ch][blk1] = blk;
blk1++; blk1++;
} }
...@@ -536,7 +540,7 @@ static void group_exponents(AC3EncodeContext *s) ...@@ -536,7 +540,7 @@ static void group_exponents(AC3EncodeContext *s)
int exp0, exp1; int exp0, exp1;
bit_count = 0; bit_count = 0;
for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) { for (blk = 0; blk < s->num_blocks; blk++) {
AC3Block *block = &s->blocks[blk]; AC3Block *block = &s->blocks[blk];
for (ch = !block->cpl_in_use; ch <= s->channels; ch++) { for (ch = !block->cpl_in_use; ch <= s->channels; ch++) {
int exp_strategy = s->exp_strategy[ch][blk]; int exp_strategy = s->exp_strategy[ch][blk];
...@@ -625,30 +629,38 @@ static void count_frame_bits_fixed(AC3EncodeContext *s) ...@@ -625,30 +629,38 @@ static void count_frame_bits_fixed(AC3EncodeContext *s)
if (s->eac3) { if (s->eac3) {
/* bitstream info header */ /* bitstream info header */
frame_bits += 35; frame_bits += 35;
frame_bits += 1 + 1 + 1; frame_bits += 1 + 1;
if (s->num_blocks != 0x6)
frame_bits++;
frame_bits++;
/* audio frame header */ /* audio frame header */
frame_bits += 2; if (s->num_blocks == 6)
frame_bits += 2;
frame_bits += 10; frame_bits += 10;
/* exponent strategy */ /* exponent strategy */
if (s->use_frame_exp_strategy) if (s->use_frame_exp_strategy)
frame_bits += 5 * s->fbw_channels; frame_bits += 5 * s->fbw_channels;
else else
frame_bits += AC3_MAX_BLOCKS * 2 * s->fbw_channels; frame_bits += s->num_blocks * 2 * s->fbw_channels;
if (s->lfe_on) if (s->lfe_on)
frame_bits += AC3_MAX_BLOCKS; frame_bits += s->num_blocks;
/* converter exponent strategy */ /* converter exponent strategy */
frame_bits += s->fbw_channels * 5; if (s->num_blks_code != 0x3)
frame_bits++;
else
frame_bits += s->fbw_channels * 5;
/* snr offsets */ /* snr offsets */
frame_bits += 10; frame_bits += 10;
/* block start info */ /* block start info */
frame_bits++; if (s->num_blocks != 1)
frame_bits++;
} else { } else {
frame_bits += 49; frame_bits += 49;
frame_bits += frame_bits_inc[s->channel_mode]; frame_bits += frame_bits_inc[s->channel_mode];
} }
/* audio blocks */ /* audio blocks */
for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) { for (blk = 0; blk < s->num_blocks; blk++) {
if (!s->eac3) { if (!s->eac3) {
/* block switch flags */ /* block switch flags */
frame_bits += s->fbw_channels; frame_bits += s->fbw_channels;
...@@ -750,7 +762,7 @@ static void count_frame_bits(AC3EncodeContext *s) ...@@ -750,7 +762,7 @@ static void count_frame_bits(AC3EncodeContext *s)
/* coupling */ /* coupling */
if (s->channel_mode > AC3_CHMODE_MONO) { if (s->channel_mode > AC3_CHMODE_MONO) {
frame_bits++; frame_bits++;
for (blk = 1; blk < AC3_MAX_BLOCKS; blk++) { for (blk = 1; blk < s->num_blocks; blk++) {
AC3Block *block = &s->blocks[blk]; AC3Block *block = &s->blocks[blk];
frame_bits++; frame_bits++;
if (block->new_cpl_strategy) if (block->new_cpl_strategy)
...@@ -762,7 +774,7 @@ static void count_frame_bits(AC3EncodeContext *s) ...@@ -762,7 +774,7 @@ static void count_frame_bits(AC3EncodeContext *s)
if (s->use_frame_exp_strategy) { if (s->use_frame_exp_strategy) {
frame_bits += 5 * s->cpl_on; frame_bits += 5 * s->cpl_on;
} else { } else {
for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) for (blk = 0; blk < s->num_blocks; blk++)
frame_bits += 2 * s->blocks[blk].cpl_in_use; frame_bits += 2 * s->blocks[blk].cpl_in_use;
} }
} }
...@@ -778,7 +790,7 @@ static void count_frame_bits(AC3EncodeContext *s) ...@@ -778,7 +790,7 @@ static void count_frame_bits(AC3EncodeContext *s)
} }
/* audio blocks */ /* audio blocks */
for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) { for (blk = 0; blk < s->num_blocks; blk++) {
AC3Block *block = &s->blocks[blk]; AC3Block *block = &s->blocks[blk];
/* coupling strategy */ /* coupling strategy */
...@@ -865,7 +877,7 @@ static void bit_alloc_masking(AC3EncodeContext *s) ...@@ -865,7 +877,7 @@ static void bit_alloc_masking(AC3EncodeContext *s)
{ {
int blk, ch; int blk, ch;
for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) { for (blk = 0; blk < s->num_blocks; blk++) {
AC3Block *block = &s->blocks[blk]; AC3Block *block = &s->blocks[blk];
for (ch = !block->cpl_in_use; ch <= s->channels; ch++) { for (ch = !block->cpl_in_use; ch <= s->channels; ch++) {
/* We only need psd and mask for calculating bap. /* We only need psd and mask for calculating bap.
...@@ -901,9 +913,9 @@ static void reset_block_bap(AC3EncodeContext *s) ...@@ -901,9 +913,9 @@ static void reset_block_bap(AC3EncodeContext *s)
ref_bap = s->bap_buffer; ref_bap = s->bap_buffer;
for (ch = 0; ch <= s->channels; ch++) { for (ch = 0; ch <= s->channels; ch++) {
for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) for (blk = 0; blk < s->num_blocks; blk++)
s->ref_bap[ch][blk] = ref_bap + AC3_MAX_COEFS * s->exp_ref_block[ch][blk]; s->ref_bap[ch][blk] = ref_bap + AC3_MAX_COEFS * s->exp_ref_block[ch][blk];
ref_bap += AC3_MAX_COEFS * AC3_MAX_BLOCKS; ref_bap += AC3_MAX_COEFS * s->num_blocks;
} }
s->ref_bap_set = 1; s->ref_bap_set = 1;
} }
...@@ -936,7 +948,7 @@ static void count_mantissa_bits_update_ch(AC3EncodeContext *s, int ch, ...@@ -936,7 +948,7 @@ static void count_mantissa_bits_update_ch(AC3EncodeContext *s, int ch,
{ {
int blk; int blk;
for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) { for (blk = 0; blk < s->num_blocks; blk++) {
AC3Block *block = &s->blocks[blk]; AC3Block *block = &s->blocks[blk];
if (ch == CPL_CH && !block->cpl_in_use) if (ch == CPL_CH && !block->cpl_in_use)
continue; continue;
...@@ -980,7 +992,7 @@ static int bit_alloc(AC3EncodeContext *s, int snr_offset) ...@@ -980,7 +992,7 @@ static int bit_alloc(AC3EncodeContext *s, int snr_offset)
snr_offset = (snr_offset - 240) << 2; snr_offset = (snr_offset - 240) << 2;
reset_block_bap(s); reset_block_bap(s);
for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) { for (blk = 0; blk < s->num_blocks; blk++) {
AC3Block *block = &s->blocks[blk]; AC3Block *block = &s->blocks[blk];
for (ch = !block->cpl_in_use; ch <= s->channels; ch++) { for (ch = !block->cpl_in_use; ch <= s->channels; ch++) {
...@@ -1194,7 +1206,7 @@ void ff_ac3_quantize_mantissas(AC3EncodeContext *s) ...@@ -1194,7 +1206,7 @@ void ff_ac3_quantize_mantissas(AC3EncodeContext *s)
{ {
int blk, ch, ch0=0, got_cpl; int blk, ch, ch0=0, got_cpl;
for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) { for (blk = 0; blk < s->num_blocks; blk++) {
AC3Block *block = &s->blocks[blk]; AC3Block *block = &s->blocks[blk];
AC3Mant m = { 0 }; AC3Mant m = { 0 };
...@@ -1557,7 +1569,7 @@ void ff_ac3_output_frame(AC3EncodeContext *s, unsigned char *frame) ...@@ -1557,7 +1569,7 @@ void ff_ac3_output_frame(AC3EncodeContext *s, unsigned char *frame)
s->output_frame_header(s); s->output_frame_header(s);
for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) for (blk = 0; blk < s->num_blocks; blk++)
output_audio_block(s, blk); output_audio_block(s, blk);
output_frame_end(s); output_frame_end(s);
...@@ -1585,6 +1597,7 @@ static void dprint_options(AC3EncodeContext *s) ...@@ -1585,6 +1597,7 @@ static void dprint_options(AC3EncodeContext *s)
av_dlog(avctx, "channel_layout: %s\n", strbuf); av_dlog(avctx, "channel_layout: %s\n", strbuf);
av_dlog(avctx, "sample_rate: %d\n", s->sample_rate); av_dlog(avctx, "sample_rate: %d\n", s->sample_rate);
av_dlog(avctx, "bit_rate: %d\n", s->bit_rate); av_dlog(avctx, "bit_rate: %d\n", s->bit_rate);
av_dlog(avctx, "blocks/frame: %d (code=%d)\n", s->num_blocks, s->num_blks_code);
if (s->cutoff) if (s->cutoff)
av_dlog(avctx, "cutoff: %d\n", s->cutoff); av_dlog(avctx, "cutoff: %d\n", s->cutoff);
...@@ -1851,7 +1864,7 @@ av_cold int ff_ac3_encode_close(AVCodecContext *avctx) ...@@ -1851,7 +1864,7 @@ av_cold int ff_ac3_encode_close(AVCodecContext *avctx)
av_freep(&s->qmant_buffer); av_freep(&s->qmant_buffer);
av_freep(&s->cpl_coord_exp_buffer); av_freep(&s->cpl_coord_exp_buffer);
av_freep(&s->cpl_coord_mant_buffer); av_freep(&s->cpl_coord_mant_buffer);
for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) { for (blk = 0; blk < s->num_blocks; blk++) {
AC3Block *block = &s->blocks[blk]; AC3Block *block = &s->blocks[blk];
av_freep(&block->mdct_coef); av_freep(&block->mdct_coef);
av_freep(&block->fixed_coef); av_freep(&block->fixed_coef);
...@@ -1958,18 +1971,30 @@ static av_cold int validate_options(AC3EncodeContext *s) ...@@ -1958,18 +1971,30 @@ static av_cold int validate_options(AC3EncodeContext *s)
/* validate bit rate */ /* validate bit rate */
if (s->eac3) { if (s->eac3) {
int max_br, min_br, wpf, min_br_dist, min_br_code; int max_br, min_br, wpf, min_br_dist, min_br_code;
int num_blks_code, num_blocks, frame_samples;
/* calculate min/max bitrate */ /* calculate min/max bitrate */
max_br = 2048 * s->sample_rate / AC3_FRAME_SIZE * 16; /* TODO: More testing with 3 and 2 blocks. All E-AC-3 samples I've
min_br = ((s->sample_rate + (AC3_FRAME_SIZE-1)) / AC3_FRAME_SIZE) * 16; found use either 6 blocks or 1 block, even though 2 or 3 blocks
would work as far as the bit rate is concerned. */
for (num_blks_code = 3; num_blks_code >= 0; num_blks_code--) {
num_blocks = ((int[]){ 1, 2, 3, 6 })[num_blks_code];
frame_samples = AC3_BLOCK_SIZE * num_blocks;
max_br = 2048 * s->sample_rate / frame_samples * 16;
min_br = ((s->sample_rate + (frame_samples-1)) / frame_samples) * 16;
if (avctx->bit_rate <= max_br)
break;
}
if (avctx->bit_rate < min_br || avctx->bit_rate > max_br) { if (avctx->bit_rate < min_br || avctx->bit_rate > max_br) {
av_log(avctx, AV_LOG_ERROR, "invalid bit rate. must be %d to %d " av_log(avctx, AV_LOG_ERROR, "invalid bit rate. must be %d to %d "
"for this sample rate\n", min_br, max_br); "for this sample rate\n", min_br, max_br);
return AVERROR(EINVAL); return AVERROR(EINVAL);
} }
s->num_blks_code = num_blks_code;
s->num_blocks = num_blocks;
/* calculate words-per-frame for the selected bitrate */ /* calculate words-per-frame for the selected bitrate */
wpf = (avctx->bit_rate / 16) * AC3_FRAME_SIZE / s->sample_rate; wpf = (avctx->bit_rate / 16) * frame_samples / s->sample_rate;
av_assert1(wpf > 0 && wpf <= 2048); av_assert1(wpf > 0 && wpf <= 2048);
/* find the closest AC-3 bitrate code to the selected bitrate. /* find the closest AC-3 bitrate code to the selected bitrate.
...@@ -2001,6 +2026,8 @@ static av_cold int validate_options(AC3EncodeContext *s) ...@@ -2001,6 +2026,8 @@ static av_cold int validate_options(AC3EncodeContext *s)
} }
s->frame_size_code = i << 1; s->frame_size_code = i << 1;
s->frame_size_min = 2 * ff_ac3_frame_size_tab[s->frame_size_code][s->bit_alloc.sr_code]; s->frame_size_min = 2 * ff_ac3_frame_size_tab[s->frame_size_code][s->bit_alloc.sr_code];
s->num_blks_code = 0x3;
s->num_blocks = 6;
} }
s->bit_rate = avctx->bit_rate; s->bit_rate = avctx->bit_rate;
s->frame_size = s->frame_size_min; s->frame_size = s->frame_size_min;
...@@ -2065,13 +2092,13 @@ static av_cold void set_bandwidth(AC3EncodeContext *s) ...@@ -2065,13 +2092,13 @@ static av_cold void set_bandwidth(AC3EncodeContext *s)
/* set number of coefficients for each channel */ /* set number of coefficients for each channel */
for (ch = 1; ch <= s->fbw_channels; ch++) { for (ch = 1; ch <= s->fbw_channels; ch++) {
s->start_freq[ch] = 0; s->start_freq[ch] = 0;
for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) for (blk = 0; blk < s->num_blocks; blk++)
s->blocks[blk].end_freq[ch] = s->bandwidth_code * 3 + 73; s->blocks[blk].end_freq[ch] = s->bandwidth_code * 3 + 73;
} }
/* LFE channel always has 7 coefs */ /* LFE channel always has 7 coefs */
if (s->lfe_on) { if (s->lfe_on) {
s->start_freq[s->lfe_channel] = 0; s->start_freq[s->lfe_channel] = 0;
for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) for (blk = 0; blk < s->num_blocks; blk++)
s->blocks[blk].end_freq[ch] = 7; s->blocks[blk].end_freq[ch] = 7;
} }
...@@ -2108,7 +2135,7 @@ static av_cold void set_bandwidth(AC3EncodeContext *s) ...@@ -2108,7 +2135,7 @@ static av_cold void set_bandwidth(AC3EncodeContext *s)
s->start_freq[CPL_CH] = cpl_start_band * 12 + 37; s->start_freq[CPL_CH] = cpl_start_band * 12 + 37;
s->cpl_end_freq = cpl_end_band * 12 + 37; s->cpl_end_freq = cpl_end_band * 12 + 37;
for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) for (blk = 0; blk < s->num_blocks; blk++)
s->blocks[blk].end_freq[CPL_CH] = s->cpl_end_freq; s->blocks[blk].end_freq[CPL_CH] = s->cpl_end_freq;
} }
} }
...@@ -2119,35 +2146,37 @@ static av_cold int allocate_buffers(AC3EncodeContext *s) ...@@ -2119,35 +2146,37 @@ static av_cold int allocate_buffers(AC3EncodeContext *s)
AVCodecContext *avctx = s->avctx; AVCodecContext *avctx = s->avctx;
int blk, ch; int blk, ch;
int channels = s->channels + 1; /* includes coupling channel */ int channels = s->channels + 1; /* includes coupling channel */
int channel_blocks = channels * s->num_blocks;
int total_coefs = AC3_MAX_COEFS * channel_blocks;
if (s->allocate_sample_buffers(s)) if (s->allocate_sample_buffers(s))
goto alloc_fail; goto alloc_fail;
FF_ALLOC_OR_GOTO(avctx, s->bap_buffer, AC3_MAX_BLOCKS * channels * FF_ALLOC_OR_GOTO(avctx, s->bap_buffer, total_coefs *
AC3_MAX_COEFS * sizeof(*s->bap_buffer), alloc_fail); sizeof(*s->bap_buffer), alloc_fail);
FF_ALLOC_OR_GOTO(avctx, s->bap1_buffer, AC3_MAX_BLOCKS * channels * FF_ALLOC_OR_GOTO(avctx, s->bap1_buffer, total_coefs *
AC3_MAX_COEFS * sizeof(*s->bap1_buffer), alloc_fail); sizeof(*s->bap1_buffer), alloc_fail);
FF_ALLOCZ_OR_GOTO(avctx, s->mdct_coef_buffer, AC3_MAX_BLOCKS * channels * FF_ALLOCZ_OR_GOTO(avctx, s->mdct_coef_buffer, total_coefs *
AC3_MAX_COEFS * sizeof(*s->mdct_coef_buffer), alloc_fail); sizeof(*s->mdct_coef_buffer), alloc_fail);
FF_ALLOC_OR_GOTO(avctx, s->exp_buffer, AC3_MAX_BLOCKS * channels * FF_ALLOC_OR_GOTO(avctx, s->exp_buffer, total_coefs *
AC3_MAX_COEFS * sizeof(*s->exp_buffer), alloc_fail); sizeof(*s->exp_buffer), alloc_fail);
FF_ALLOC_OR_GOTO(avctx, s->grouped_exp_buffer, AC3_MAX_BLOCKS * channels * FF_ALLOC_OR_GOTO(avctx, s->grouped_exp_buffer, channel_blocks * 128 *
128 * sizeof(*s->grouped_exp_buffer), alloc_fail); sizeof(*s->grouped_exp_buffer), alloc_fail);
FF_ALLOC_OR_GOTO(avctx, s->psd_buffer, AC3_MAX_BLOCKS * channels * FF_ALLOC_OR_GOTO(avctx, s->psd_buffer, total_coefs *
AC3_MAX_COEFS * sizeof(*s->psd_buffer), alloc_fail); sizeof(*s->psd_buffer), alloc_fail);
FF_ALLOC_OR_GOTO(avctx, s->band_psd_buffer, AC3_MAX_BLOCKS * channels * FF_ALLOC_OR_GOTO(avctx, s->band_psd_buffer, channel_blocks * 64 *
64 * sizeof(*s->band_psd_buffer), alloc_fail); sizeof(*s->band_psd_buffer), alloc_fail);
FF_ALLOC_OR_GOTO(avctx, s->mask_buffer, AC3_MAX_BLOCKS * channels * FF_ALLOC_OR_GOTO(avctx, s->mask_buffer, channel_blocks * 64 *
64 * sizeof(*s->mask_buffer), alloc_fail); sizeof(*s->mask_buffer), alloc_fail);
FF_ALLOC_OR_GOTO(avctx, s->qmant_buffer, AC3_MAX_BLOCKS * channels * FF_ALLOC_OR_GOTO(avctx, s->qmant_buffer, total_coefs *
AC3_MAX_COEFS * sizeof(*s->qmant_buffer), alloc_fail); sizeof(*s->qmant_buffer), alloc_fail);
if (s->cpl_enabled) { if (s->cpl_enabled) {
FF_ALLOC_OR_GOTO(avctx, s->cpl_coord_exp_buffer, AC3_MAX_BLOCKS * channels * FF_ALLOC_OR_GOTO(avctx, s->cpl_coord_exp_buffer, channel_blocks * 16 *
16 * sizeof(*s->cpl_coord_exp_buffer), alloc_fail); sizeof(*s->cpl_coord_exp_buffer), alloc_fail);
FF_ALLOC_OR_GOTO(avctx, s->cpl_coord_mant_buffer, AC3_MAX_BLOCKS * channels * FF_ALLOC_OR_GOTO(avctx, s->cpl_coord_mant_buffer, channel_blocks * 16 *
16 * sizeof(*s->cpl_coord_mant_buffer), alloc_fail); sizeof(*s->cpl_coord_mant_buffer), alloc_fail);
} }
for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) { for (blk = 0; blk < s->num_blocks; blk++) {
AC3Block *block = &s->blocks[blk]; AC3Block *block = &s->blocks[blk];
FF_ALLOCZ_OR_GOTO(avctx, block->mdct_coef, channels * sizeof(*block->mdct_coef), FF_ALLOCZ_OR_GOTO(avctx, block->mdct_coef, channels * sizeof(*block->mdct_coef),
alloc_fail); alloc_fail);
...@@ -2183,23 +2212,23 @@ static av_cold int allocate_buffers(AC3EncodeContext *s) ...@@ -2183,23 +2212,23 @@ static av_cold int allocate_buffers(AC3EncodeContext *s)
} }
/* arrangement: channel, block, coeff */ /* arrangement: channel, block, coeff */
block->exp[ch] = &s->exp_buffer [AC3_MAX_COEFS * (AC3_MAX_BLOCKS * ch + blk)]; block->exp[ch] = &s->exp_buffer [AC3_MAX_COEFS * (s->num_blocks * ch + blk)];
block->mdct_coef[ch] = &s->mdct_coef_buffer [AC3_MAX_COEFS * (AC3_MAX_BLOCKS * ch + blk)]; block->mdct_coef[ch] = &s->mdct_coef_buffer [AC3_MAX_COEFS * (s->num_blocks * ch + blk)];
} }
} }
if (!s->fixed_point) { if (!s->fixed_point) {
FF_ALLOCZ_OR_GOTO(avctx, s->fixed_coef_buffer, AC3_MAX_BLOCKS * channels * FF_ALLOCZ_OR_GOTO(avctx, s->fixed_coef_buffer, total_coefs *
AC3_MAX_COEFS * sizeof(*s->fixed_coef_buffer), alloc_fail); sizeof(*s->fixed_coef_buffer), alloc_fail);
for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) { for (blk = 0; blk < s->num_blocks; blk++) {
AC3Block *block = &s->blocks[blk]; AC3Block *block = &s->blocks[blk];
FF_ALLOCZ_OR_GOTO(avctx, block->fixed_coef, channels * FF_ALLOCZ_OR_GOTO(avctx, block->fixed_coef, channels *
sizeof(*block->fixed_coef), alloc_fail); sizeof(*block->fixed_coef), alloc_fail);
for (ch = 0; ch < channels; ch++) for (ch = 0; ch < channels; ch++)
block->fixed_coef[ch] = &s->fixed_coef_buffer[AC3_MAX_COEFS * (AC3_MAX_BLOCKS * ch + blk)]; block->fixed_coef[ch] = &s->fixed_coef_buffer[AC3_MAX_COEFS * (s->num_blocks * ch + blk)];
} }
} else { } else {
for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) { for (blk = 0; blk < s->num_blocks; blk++) {
AC3Block *block = &s->blocks[blk]; AC3Block *block = &s->blocks[blk];
FF_ALLOCZ_OR_GOTO(avctx, block->fixed_coef, channels * FF_ALLOCZ_OR_GOTO(avctx, block->fixed_coef, channels *
sizeof(*block->fixed_coef), alloc_fail); sizeof(*block->fixed_coef), alloc_fail);
...@@ -2226,14 +2255,14 @@ av_cold int ff_ac3_encode_init(AVCodecContext *avctx) ...@@ -2226,14 +2255,14 @@ av_cold int ff_ac3_encode_init(AVCodecContext *avctx)
s->eac3 = avctx->codec_id == CODEC_ID_EAC3; s->eac3 = avctx->codec_id == CODEC_ID_EAC3;
avctx->frame_size = AC3_FRAME_SIZE;
ff_ac3_common_init(); ff_ac3_common_init();
ret = validate_options(s); ret = validate_options(s);
if (ret) if (ret)
return ret; return ret;
avctx->frame_size = AC3_BLOCK_SIZE * s->num_blocks;
s->bitstream_mode = avctx->audio_service_type; s->bitstream_mode = avctx->audio_service_type;
if (s->bitstream_mode == AV_AUDIO_SERVICE_TYPE_KARAOKE) if (s->bitstream_mode == AV_AUDIO_SERVICE_TYPE_KARAOKE)
s->bitstream_mode = 0x7; s->bitstream_mode = 0x7;
......
...@@ -151,6 +151,8 @@ typedef struct AC3EncodeContext { ...@@ -151,6 +151,8 @@ typedef struct AC3EncodeContext {
int bit_rate; ///< target bit rate, in bits-per-second int bit_rate; ///< target bit rate, in bits-per-second
int sample_rate; ///< sampling frequency, in Hz int sample_rate; ///< sampling frequency, in Hz
int num_blks_code; ///< number of blocks code (numblkscod)
int num_blocks; ///< number of blocks per frame
int frame_size_min; ///< minimum frame size in case rounding is necessary int frame_size_min; ///< minimum frame size in case rounding is necessary
int frame_size; ///< current frame size in bytes int frame_size; ///< current frame size in bytes
int frame_size_code; ///< frame size code (frmsizecod) int frame_size_code; ///< frame size code (frmsizecod)
......
...@@ -93,7 +93,7 @@ static void scale_coefficients(AC3EncodeContext *s) ...@@ -93,7 +93,7 @@ static void scale_coefficients(AC3EncodeContext *s)
{ {
int blk, ch; int blk, ch;
for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) { for (blk = 0; blk < s->num_blocks; blk++) {
AC3Block *block = &s->blocks[blk]; AC3Block *block = &s->blocks[blk];
for (ch = 1; ch <= s->channels; ch++) { for (ch = 1; ch <= s->channels; ch++) {
s->ac3dsp.ac3_rshift_int32(block->mdct_coef[ch], AC3_MAX_COEFS, s->ac3dsp.ac3_rshift_int32(block->mdct_coef[ch], AC3_MAX_COEFS,
......
...@@ -103,7 +103,7 @@ static int normalize_samples(AC3EncodeContext *s) ...@@ -103,7 +103,7 @@ static int normalize_samples(AC3EncodeContext *s)
*/ */
static void scale_coefficients(AC3EncodeContext *s) static void scale_coefficients(AC3EncodeContext *s)
{ {
int chan_size = AC3_MAX_COEFS * AC3_MAX_BLOCKS; int chan_size = AC3_MAX_COEFS * s->num_blocks;
s->ac3dsp.float_to_fixed24(s->fixed_coef_buffer + chan_size, s->ac3dsp.float_to_fixed24(s->fixed_coef_buffer + chan_size,
s->mdct_coef_buffer + chan_size, s->mdct_coef_buffer + chan_size,
chan_size * s->channels); chan_size * s->channels);
......
...@@ -79,13 +79,13 @@ static void deinterleave_input_samples(AC3EncodeContext *s, ...@@ -79,13 +79,13 @@ static void deinterleave_input_samples(AC3EncodeContext *s,
int sinc; int sinc;
/* copy last 256 samples of previous frame to the start of the current frame */ /* copy last 256 samples of previous frame to the start of the current frame */
memcpy(&s->planar_samples[ch][0], &s->planar_samples[ch][AC3_FRAME_SIZE], memcpy(&s->planar_samples[ch][0], &s->planar_samples[ch][AC3_BLOCK_SIZE * s->num_blocks],
AC3_BLOCK_SIZE * sizeof(s->planar_samples[0][0])); AC3_BLOCK_SIZE * sizeof(s->planar_samples[0][0]));
/* deinterleave */ /* deinterleave */
sinc = s->channels; sinc = s->channels;
sptr = samples + s->channel_map[ch]; sptr = samples + s->channel_map[ch];
for (i = AC3_BLOCK_SIZE; i < AC3_FRAME_SIZE+AC3_BLOCK_SIZE; i++) { for (i = AC3_BLOCK_SIZE; i < AC3_BLOCK_SIZE * (s->num_blocks + 1); i++) {
s->planar_samples[ch][i] = *sptr; s->planar_samples[ch][i] = *sptr;
sptr += sinc; sptr += sinc;
} }
...@@ -103,7 +103,7 @@ static void apply_mdct(AC3EncodeContext *s) ...@@ -103,7 +103,7 @@ static void apply_mdct(AC3EncodeContext *s)
int blk, ch; int blk, ch;
for (ch = 0; ch < s->channels; ch++) { for (ch = 0; ch < s->channels; ch++) {
for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) { for (blk = 0; blk < s->num_blocks; blk++) {
AC3Block *block = &s->blocks[blk]; AC3Block *block = &s->blocks[blk];
const SampleType *input_samples = &s->planar_samples[ch][blk * AC3_BLOCK_SIZE]; const SampleType *input_samples = &s->planar_samples[ch][blk * AC3_BLOCK_SIZE];
...@@ -159,7 +159,7 @@ static void apply_channel_coupling(AC3EncodeContext *s) ...@@ -159,7 +159,7 @@ static void apply_channel_coupling(AC3EncodeContext *s)
cpl_start = FFMIN(256, cpl_start + num_cpl_coefs) - num_cpl_coefs; cpl_start = FFMIN(256, cpl_start + num_cpl_coefs) - num_cpl_coefs;
/* calculate coupling channel from fbw channels */ /* calculate coupling channel from fbw channels */
for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) { for (blk = 0; blk < s->num_blocks; blk++) {
AC3Block *block = &s->blocks[blk]; AC3Block *block = &s->blocks[blk];
CoefType *cpl_coef = &block->mdct_coef[CPL_CH][cpl_start]; CoefType *cpl_coef = &block->mdct_coef[CPL_CH][cpl_start];
if (!block->cpl_in_use) if (!block->cpl_in_use)
...@@ -188,7 +188,7 @@ static void apply_channel_coupling(AC3EncodeContext *s) ...@@ -188,7 +188,7 @@ static void apply_channel_coupling(AC3EncodeContext *s)
while (i < s->cpl_end_freq) { while (i < s->cpl_end_freq) {
int band_size = s->cpl_band_sizes[bnd]; int band_size = s->cpl_band_sizes[bnd];
for (ch = CPL_CH; ch <= s->fbw_channels; ch++) { for (ch = CPL_CH; ch <= s->fbw_channels; ch++) {
for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) { for (blk = 0; blk < s->num_blocks; blk++) {
AC3Block *block = &s->blocks[blk]; AC3Block *block = &s->blocks[blk];
if (!block->cpl_in_use || (ch > CPL_CH && !block->channel_in_cpl[ch])) if (!block->cpl_in_use || (ch > CPL_CH && !block->channel_in_cpl[ch]))
continue; continue;
...@@ -203,7 +203,7 @@ static void apply_channel_coupling(AC3EncodeContext *s) ...@@ -203,7 +203,7 @@ static void apply_channel_coupling(AC3EncodeContext *s)
} }
/* determine which blocks to send new coupling coordinates for */ /* determine which blocks to send new coupling coordinates for */
for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) { for (blk = 0; blk < s->num_blocks; blk++) {
AC3Block *block = &s->blocks[blk]; AC3Block *block = &s->blocks[blk];
AC3Block *block0 = blk ? &s->blocks[blk-1] : NULL; AC3Block *block0 = blk ? &s->blocks[blk-1] : NULL;
int new_coords = 0; int new_coords = 0;
...@@ -261,7 +261,7 @@ static void apply_channel_coupling(AC3EncodeContext *s) ...@@ -261,7 +261,7 @@ static void apply_channel_coupling(AC3EncodeContext *s)
coordinates in successive blocks */ coordinates in successive blocks */
for (bnd = 0; bnd < s->num_cpl_bands; bnd++) { for (bnd = 0; bnd < s->num_cpl_bands; bnd++) {
blk = 0; blk = 0;
while (blk < AC3_MAX_BLOCKS) { while (blk < s->num_blocks) {
int blk1; int blk1;
CoefSumType energy_cpl; CoefSumType energy_cpl;
AC3Block *block = &s->blocks[blk]; AC3Block *block = &s->blocks[blk];
...@@ -273,7 +273,7 @@ static void apply_channel_coupling(AC3EncodeContext *s) ...@@ -273,7 +273,7 @@ static void apply_channel_coupling(AC3EncodeContext *s)
energy_cpl = energy[blk][CPL_CH][bnd]; energy_cpl = energy[blk][CPL_CH][bnd];
blk1 = blk+1; blk1 = blk+1;
while (!s->blocks[blk1].new_cpl_coords && blk1 < AC3_MAX_BLOCKS) { while (!s->blocks[blk1].new_cpl_coords && blk1 < s->num_blocks) {
if (s->blocks[blk1].cpl_in_use) if (s->blocks[blk1].cpl_in_use)
energy_cpl += energy[blk1][CPL_CH][bnd]; energy_cpl += energy[blk1][CPL_CH][bnd];
blk1++; blk1++;
...@@ -285,7 +285,7 @@ static void apply_channel_coupling(AC3EncodeContext *s) ...@@ -285,7 +285,7 @@ static void apply_channel_coupling(AC3EncodeContext *s)
continue; continue;
energy_ch = energy[blk][ch][bnd]; energy_ch = energy[blk][ch][bnd];
blk1 = blk+1; blk1 = blk+1;
while (!s->blocks[blk1].new_cpl_coords && blk1 < AC3_MAX_BLOCKS) { while (!s->blocks[blk1].new_cpl_coords && blk1 < s->num_blocks) {
if (s->blocks[blk1].cpl_in_use) if (s->blocks[blk1].cpl_in_use)
energy_ch += energy[blk1][ch][bnd]; energy_ch += energy[blk1][ch][bnd];
blk1++; blk1++;
...@@ -297,7 +297,7 @@ static void apply_channel_coupling(AC3EncodeContext *s) ...@@ -297,7 +297,7 @@ static void apply_channel_coupling(AC3EncodeContext *s)
} }
/* calculate exponents/mantissas for coupling coordinates */ /* calculate exponents/mantissas for coupling coordinates */
for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) { for (blk = 0; blk < s->num_blocks; blk++) {
AC3Block *block = &s->blocks[blk]; AC3Block *block = &s->blocks[blk];
if (!block->cpl_in_use || !block->new_cpl_coords) if (!block->cpl_in_use || !block->new_cpl_coords)
continue; continue;
...@@ -362,7 +362,7 @@ static void compute_rematrixing_strategy(AC3EncodeContext *s) ...@@ -362,7 +362,7 @@ static void compute_rematrixing_strategy(AC3EncodeContext *s)
if (s->channel_mode != AC3_CHMODE_STEREO) if (s->channel_mode != AC3_CHMODE_STEREO)
return; return;
for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) { for (blk = 0; blk < s->num_blocks; blk++) {
block = &s->blocks[blk]; block = &s->blocks[blk];
block->new_rematrixing_strategy = !blk; block->new_rematrixing_strategy = !blk;
...@@ -440,7 +440,7 @@ int AC3_NAME(encode_frame)(AVCodecContext *avctx, unsigned char *frame, ...@@ -440,7 +440,7 @@ int AC3_NAME(encode_frame)(AVCodecContext *avctx, unsigned char *frame,
scale_coefficients(s); scale_coefficients(s);
clip_coefficients(&s->dsp, s->blocks[0].mdct_coef[1], clip_coefficients(&s->dsp, s->blocks[0].mdct_coef[1],
AC3_MAX_COEFS * AC3_MAX_BLOCKS * s->channels); AC3_MAX_COEFS * s->num_blocks * s->channels);
s->cpl_on = s->cpl_enabled; s->cpl_on = s->cpl_enabled;
ff_ac3_compute_coupling_strategy(s); ff_ac3_compute_coupling_strategy(s);
......
...@@ -63,6 +63,11 @@ void ff_eac3_get_frame_exp_strategy(AC3EncodeContext *s) ...@@ -63,6 +63,11 @@ void ff_eac3_get_frame_exp_strategy(AC3EncodeContext *s)
{ {
int ch; int ch;
if (s->num_blocks < 6) {
s->use_frame_exp_strategy = 0;
return;
}
s->use_frame_exp_strategy = 1; s->use_frame_exp_strategy = 1;
for (ch = !s->cpl_on; ch <= s->fbw_channels; ch++) { for (ch = !s->cpl_on; ch <= s->fbw_channels; ch++) {
int expstr = eac3_frame_expstr_index_tab[s->exp_strategy[ch][0]-1] int expstr = eac3_frame_expstr_index_tab[s->exp_strategy[ch][0]-1]
...@@ -89,7 +94,7 @@ void ff_eac3_set_cpl_states(AC3EncodeContext *s) ...@@ -89,7 +94,7 @@ void ff_eac3_set_cpl_states(AC3EncodeContext *s)
/* set first cpl coords */ /* set first cpl coords */
for (ch = 1; ch <= s->fbw_channels; ch++) for (ch = 1; ch <= s->fbw_channels; ch++)
first_cpl_coords[ch] = 1; first_cpl_coords[ch] = 1;
for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) { for (blk = 0; blk < s->num_blocks; blk++) {
AC3Block *block = &s->blocks[blk]; AC3Block *block = &s->blocks[blk];
for (ch = 1; ch <= s->fbw_channels; ch++) { for (ch = 1; ch <= s->fbw_channels; ch++) {
if (block->channel_in_cpl[ch]) { if (block->channel_in_cpl[ch]) {
...@@ -104,7 +109,7 @@ void ff_eac3_set_cpl_states(AC3EncodeContext *s) ...@@ -104,7 +109,7 @@ void ff_eac3_set_cpl_states(AC3EncodeContext *s)
} }
/* set first cpl leak */ /* set first cpl leak */
for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) { for (blk = 0; blk < s->num_blocks; blk++) {
AC3Block *block = &s->blocks[blk]; AC3Block *block = &s->blocks[blk];
if (block->cpl_in_use) { if (block->cpl_in_use) {
block->new_cpl_leak = 2; block->new_cpl_leak = 2;
...@@ -130,7 +135,7 @@ void ff_eac3_output_frame_header(AC3EncodeContext *s) ...@@ -130,7 +135,7 @@ void ff_eac3_output_frame_header(AC3EncodeContext *s)
put_bits(&s->pb, 2, s->bit_alloc.sr_code); /* sample rate code */ put_bits(&s->pb, 2, s->bit_alloc.sr_code); /* sample rate code */
} else { } else {
put_bits(&s->pb, 2, s->bit_alloc.sr_code); /* sample rate code */ put_bits(&s->pb, 2, s->bit_alloc.sr_code); /* sample rate code */
put_bits(&s->pb, 2, 0x3); /* number of blocks = 6 */ put_bits(&s->pb, 2, s->num_blks_code); /* number of blocks */
} }
put_bits(&s->pb, 3, s->channel_mode); /* audio coding mode */ put_bits(&s->pb, 3, s->channel_mode); /* audio coding mode */
put_bits(&s->pb, 1, s->lfe_on); /* LFE channel indicator */ put_bits(&s->pb, 1, s->lfe_on); /* LFE channel indicator */
...@@ -141,11 +146,15 @@ void ff_eac3_output_frame_header(AC3EncodeContext *s) ...@@ -141,11 +146,15 @@ void ff_eac3_output_frame_header(AC3EncodeContext *s)
/* TODO: mixing metadata */ /* TODO: mixing metadata */
put_bits(&s->pb, 1, 0); /* no info metadata */ put_bits(&s->pb, 1, 0); /* no info metadata */
/* TODO: info metadata */ /* TODO: info metadata */
if (s->num_blocks != 6)
put_bits(&s->pb, 1, !(s->avctx->frame_number % 6)); /* converter sync flag */
put_bits(&s->pb, 1, 0); /* no additional bit stream info */ put_bits(&s->pb, 1, 0); /* no additional bit stream info */
/* frame header */ /* frame header */
if (s->num_blocks == 6) {
put_bits(&s->pb, 1, !s->use_frame_exp_strategy);/* exponent strategy syntax */ put_bits(&s->pb, 1, !s->use_frame_exp_strategy);/* exponent strategy syntax */
put_bits(&s->pb, 1, 0); /* aht enabled = no */ put_bits(&s->pb, 1, 0); /* aht enabled = no */
}
put_bits(&s->pb, 2, 0); /* snr offset strategy = 1 */ put_bits(&s->pb, 2, 0); /* snr offset strategy = 1 */
put_bits(&s->pb, 1, 0); /* transient pre-noise processing enabled = no */ put_bits(&s->pb, 1, 0); /* transient pre-noise processing enabled = no */
put_bits(&s->pb, 1, 0); /* block switch syntax enabled = no */ put_bits(&s->pb, 1, 0); /* block switch syntax enabled = no */
...@@ -158,7 +167,7 @@ void ff_eac3_output_frame_header(AC3EncodeContext *s) ...@@ -158,7 +167,7 @@ void ff_eac3_output_frame_header(AC3EncodeContext *s)
/* coupling strategy use flags */ /* coupling strategy use flags */
if (s->channel_mode > AC3_CHMODE_MONO) { if (s->channel_mode > AC3_CHMODE_MONO) {
put_bits(&s->pb, 1, s->blocks[0].cpl_in_use); put_bits(&s->pb, 1, s->blocks[0].cpl_in_use);
for (blk = 1; blk < AC3_MAX_BLOCKS; blk++) { for (blk = 1; blk < s->num_blocks; blk++) {
AC3Block *block = &s->blocks[blk]; AC3Block *block = &s->blocks[blk];
put_bits(&s->pb, 1, block->new_cpl_strategy); put_bits(&s->pb, 1, block->new_cpl_strategy);
if (block->new_cpl_strategy) if (block->new_cpl_strategy)
...@@ -170,26 +179,31 @@ void ff_eac3_output_frame_header(AC3EncodeContext *s) ...@@ -170,26 +179,31 @@ void ff_eac3_output_frame_header(AC3EncodeContext *s)
for (ch = !s->cpl_on; ch <= s->fbw_channels; ch++) for (ch = !s->cpl_on; ch <= s->fbw_channels; ch++)
put_bits(&s->pb, 5, s->frame_exp_strategy[ch]); put_bits(&s->pb, 5, s->frame_exp_strategy[ch]);
} else { } else {
for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) for (blk = 0; blk < s->num_blocks; blk++)
for (ch = !s->blocks[blk].cpl_in_use; ch <= s->fbw_channels; ch++) for (ch = !s->blocks[blk].cpl_in_use; ch <= s->fbw_channels; ch++)
put_bits(&s->pb, 2, s->exp_strategy[ch][blk]); put_bits(&s->pb, 2, s->exp_strategy[ch][blk]);
} }
if (s->lfe_on) { if (s->lfe_on) {
for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) for (blk = 0; blk < s->num_blocks; blk++)
put_bits(&s->pb, 1, s->exp_strategy[s->lfe_channel][blk]); put_bits(&s->pb, 1, s->exp_strategy[s->lfe_channel][blk]);
} }
/* E-AC-3 to AC-3 converter exponent strategy (unfortunately not optional...) */ /* E-AC-3 to AC-3 converter exponent strategy (not optional when num blocks == 6) */
if (s->num_blocks != 6) {
put_bits(&s->pb, 1, 0);
} else {
for (ch = 1; ch <= s->fbw_channels; ch++) { for (ch = 1; ch <= s->fbw_channels; ch++) {
if (s->use_frame_exp_strategy) if (s->use_frame_exp_strategy)
put_bits(&s->pb, 5, s->frame_exp_strategy[ch]); put_bits(&s->pb, 5, s->frame_exp_strategy[ch]);
else else
put_bits(&s->pb, 5, 0); put_bits(&s->pb, 5, 0);
} }
}
/* snr offsets */ /* snr offsets */
put_bits(&s->pb, 6, s->coarse_snr_offset); put_bits(&s->pb, 6, s->coarse_snr_offset);
put_bits(&s->pb, 4, s->fine_snr_offset[1]); put_bits(&s->pb, 4, s->fine_snr_offset[1]);
/* block start info */ /* block start info */
put_bits(&s->pb, 1, 0); if (s->num_blocks > 1)
put_bits(&s->pb, 1, 0);
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment