From be7bd626c4832c4bc5295a01bfd68156ac78ccba Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Thu, 14 Jul 2011 13:02:45 -0400 Subject: [PATCH] eac3enc: use different numbers of blocks per frame to allow higher bitrates --- libavcodec/ac3enc.c | 179 +++++++++++++++++++++++++------------------ libavcodec/ac3enc.h | 2 + libavcodec/ac3enc_fixed.c | 2 +- libavcodec/ac3enc_float.c | 2 +- libavcodec/ac3enc_template.c | 24 +++--- libavcodec/eac3enc.c | 30 ++++++-- 6 files changed, 142 insertions(+), 97 deletions(-) diff --git a/libavcodec/ac3enc.c b/libavcodec/ac3enc.c index e7a5b1611..017b1d4b9 100644 --- a/libavcodec/ac3enc.c +++ b/libavcodec/ac3enc.c @@ -186,7 +186,7 @@ void ff_ac3_adjust_frame_size(AC3EncodeContext *s) s->frame_size = s->frame_size_min + 2 * (s->bits_written * s->sample_rate < s->samples_written * s->bit_rate); 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) /* set coupling use flags for each block/channel */ /* 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]; for (ch = 1; ch <= s->fbw_channels; ch++) block->channel_in_cpl[ch] = s->cpl_on; @@ -208,7 +208,7 @@ void ff_ac3_compute_coupling_strategy(AC3EncodeContext *s) enabled for that block */ got_cpl_snr = 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]; block->num_cpl_channels = 0; for (ch = 1; ch <= s->fbw_channels; ch++) @@ -244,7 +244,7 @@ void ff_ac3_compute_coupling_strategy(AC3EncodeContext *s) s->cpl_on = 0; /* 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]; for (ch = 1; ch <= s->fbw_channels; ch++) { if (block->channel_in_cpl[ch]) @@ -269,7 +269,7 @@ void ff_ac3_apply_rematrixing(AC3EncodeContext *s) if (!s->rematrixing_enabled) return; - for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) { + for (blk = 0; blk < s->num_blocks; blk++) { AC3Block *block = &s->blocks[blk]; if (block->new_rematrixing_strategy) flags = block->rematrixing_flags; @@ -318,7 +318,7 @@ static av_cold void exponent_init(AC3EncodeContext *s) static void extract_exponents(AC3EncodeContext *s) { 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]; s->ac3dsp.extract_exponents(block->exp[ch], block->fixed_coef[ch], chan_size); @@ -331,6 +331,15 @@ static void extract_exponents(AC3EncodeContext *s) */ #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. @@ -349,7 +358,7 @@ static void compute_exp_strategy(AC3EncodeContext *s) reused in the next frame */ exp_strategy[0] = EXP_NEW; 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 (!s->blocks[blk-1].cpl_in_use) { exp_strategy[blk] = EXP_NEW; @@ -373,23 +382,18 @@ static void compute_exp_strategy(AC3EncodeContext *s) /* now select the encoding strategy type : if exponents are often recoded, we use a coarse encoding */ blk = 0; - while (blk < AC3_MAX_BLOCKS) { + while (blk < s->num_blocks) { blk1 = blk + 1; - while (blk1 < AC3_MAX_BLOCKS && exp_strategy[blk1] == EXP_REUSE) + while (blk1 < s->num_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; - } + exp_strategy[blk] = exp_strategy_reuse_tab[s->num_blks_code][blk1-blk-1]; blk = blk1; } } if (s->lfe_on) { ch = s->lfe_channel; 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; } @@ -487,7 +491,7 @@ static void encode_exponents(AC3EncodeContext *s) cpl = (ch == CPL_CH); blk = 0; - while (blk < AC3_MAX_BLOCKS) { + while (blk < s->num_blocks) { AC3Block *block = &s->blocks[blk]; if (cpl && !block->cpl_in_use) { exp += AC3_MAX_COEFS; @@ -500,7 +504,7 @@ static void encode_exponents(AC3EncodeContext *s) /* count the number of EXP_REUSE blocks after the current block and set exponent reference block numbers */ 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; blk1++; } @@ -536,7 +540,7 @@ static void group_exponents(AC3EncodeContext *s) int exp0, exp1; bit_count = 0; - for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) { + for (blk = 0; blk < s->num_blocks; blk++) { AC3Block *block = &s->blocks[blk]; for (ch = !block->cpl_in_use; ch <= s->channels; ch++) { int exp_strategy = s->exp_strategy[ch][blk]; @@ -625,30 +629,38 @@ static void count_frame_bits_fixed(AC3EncodeContext *s) if (s->eac3) { /* bitstream info header */ frame_bits += 35; - frame_bits += 1 + 1 + 1; + frame_bits += 1 + 1; + if (s->num_blocks != 0x6) + frame_bits++; + frame_bits++; /* audio frame header */ - frame_bits += 2; + if (s->num_blocks == 6) + frame_bits += 2; frame_bits += 10; /* exponent strategy */ if (s->use_frame_exp_strategy) frame_bits += 5 * s->fbw_channels; else - frame_bits += AC3_MAX_BLOCKS * 2 * s->fbw_channels; + frame_bits += s->num_blocks * 2 * s->fbw_channels; if (s->lfe_on) - frame_bits += AC3_MAX_BLOCKS; + frame_bits += s->num_blocks; /* 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 */ frame_bits += 10; /* block start info */ - frame_bits++; + if (s->num_blocks != 1) + frame_bits++; } else { frame_bits += 49; frame_bits += frame_bits_inc[s->channel_mode]; } /* audio blocks */ - for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) { + for (blk = 0; blk < s->num_blocks; blk++) { if (!s->eac3) { /* block switch flags */ frame_bits += s->fbw_channels; @@ -750,7 +762,7 @@ static void count_frame_bits(AC3EncodeContext *s) /* coupling */ if (s->channel_mode > AC3_CHMODE_MONO) { frame_bits++; - for (blk = 1; blk < AC3_MAX_BLOCKS; blk++) { + for (blk = 1; blk < s->num_blocks; blk++) { AC3Block *block = &s->blocks[blk]; frame_bits++; if (block->new_cpl_strategy) @@ -762,7 +774,7 @@ static void count_frame_bits(AC3EncodeContext *s) if (s->use_frame_exp_strategy) { frame_bits += 5 * s->cpl_on; } 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; } } @@ -778,7 +790,7 @@ static void count_frame_bits(AC3EncodeContext *s) } /* audio blocks */ - for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) { + for (blk = 0; blk < s->num_blocks; blk++) { AC3Block *block = &s->blocks[blk]; /* coupling strategy */ @@ -865,7 +877,7 @@ static void bit_alloc_masking(AC3EncodeContext *s) { int blk, ch; - for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) { + for (blk = 0; blk < s->num_blocks; blk++) { AC3Block *block = &s->blocks[blk]; for (ch = !block->cpl_in_use; ch <= s->channels; ch++) { /* We only need psd and mask for calculating bap. @@ -901,9 +913,9 @@ static void reset_block_bap(AC3EncodeContext *s) ref_bap = s->bap_buffer; 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]; - ref_bap += AC3_MAX_COEFS * AC3_MAX_BLOCKS; + ref_bap += AC3_MAX_COEFS * s->num_blocks; } s->ref_bap_set = 1; } @@ -936,7 +948,7 @@ static void count_mantissa_bits_update_ch(AC3EncodeContext *s, int ch, { int blk; - for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) { + for (blk = 0; blk < s->num_blocks; blk++) { AC3Block *block = &s->blocks[blk]; if (ch == CPL_CH && !block->cpl_in_use) continue; @@ -980,7 +992,7 @@ static int bit_alloc(AC3EncodeContext *s, int snr_offset) snr_offset = (snr_offset - 240) << 2; 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]; for (ch = !block->cpl_in_use; ch <= s->channels; ch++) { @@ -1194,7 +1206,7 @@ void ff_ac3_quantize_mantissas(AC3EncodeContext *s) { 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]; AC3Mant m = { 0 }; @@ -1557,7 +1569,7 @@ void ff_ac3_output_frame(AC3EncodeContext *s, unsigned char *frame) 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_frame_end(s); @@ -1585,6 +1597,7 @@ static void dprint_options(AC3EncodeContext *s) av_dlog(avctx, "channel_layout: %s\n", strbuf); av_dlog(avctx, "sample_rate: %d\n", s->sample_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) av_dlog(avctx, "cutoff: %d\n", s->cutoff); @@ -1851,7 +1864,7 @@ av_cold int ff_ac3_encode_close(AVCodecContext *avctx) av_freep(&s->qmant_buffer); av_freep(&s->cpl_coord_exp_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]; av_freep(&block->mdct_coef); av_freep(&block->fixed_coef); @@ -1958,18 +1971,30 @@ static av_cold int validate_options(AC3EncodeContext *s) /* validate bit rate */ if (s->eac3) { int max_br, min_br, wpf, min_br_dist, min_br_code; + int num_blks_code, num_blocks, frame_samples; /* calculate min/max bitrate */ - max_br = 2048 * s->sample_rate / AC3_FRAME_SIZE * 16; - min_br = ((s->sample_rate + (AC3_FRAME_SIZE-1)) / AC3_FRAME_SIZE) * 16; + /* TODO: More testing with 3 and 2 blocks. All E-AC-3 samples I've + 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) { av_log(avctx, AV_LOG_ERROR, "invalid bit rate. must be %d to %d " "for this sample rate\n", min_br, max_br); return AVERROR(EINVAL); } + s->num_blks_code = num_blks_code; + s->num_blocks = num_blocks; /* 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); /* find the closest AC-3 bitrate code to the selected bitrate. @@ -2001,6 +2026,8 @@ static av_cold int validate_options(AC3EncodeContext *s) } 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->num_blks_code = 0x3; + s->num_blocks = 6; } s->bit_rate = avctx->bit_rate; s->frame_size = s->frame_size_min; @@ -2065,13 +2092,13 @@ static av_cold void set_bandwidth(AC3EncodeContext *s) /* set number of coefficients for each channel */ for (ch = 1; ch <= s->fbw_channels; ch++) { 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; } /* LFE channel always has 7 coefs */ if (s->lfe_on) { 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; } @@ -2108,7 +2135,7 @@ static av_cold void set_bandwidth(AC3EncodeContext *s) s->start_freq[CPL_CH] = cpl_start_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; } } @@ -2119,35 +2146,37 @@ static av_cold int allocate_buffers(AC3EncodeContext *s) AVCodecContext *avctx = s->avctx; int blk, ch; 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)) goto alloc_fail; - FF_ALLOC_OR_GOTO(avctx, s->bap_buffer, AC3_MAX_BLOCKS * channels * - AC3_MAX_COEFS * sizeof(*s->bap_buffer), alloc_fail); - FF_ALLOC_OR_GOTO(avctx, s->bap1_buffer, AC3_MAX_BLOCKS * channels * - AC3_MAX_COEFS * sizeof(*s->bap1_buffer), alloc_fail); - FF_ALLOCZ_OR_GOTO(avctx, s->mdct_coef_buffer, AC3_MAX_BLOCKS * channels * - AC3_MAX_COEFS * sizeof(*s->mdct_coef_buffer), alloc_fail); - FF_ALLOC_OR_GOTO(avctx, s->exp_buffer, AC3_MAX_BLOCKS * channels * - AC3_MAX_COEFS * sizeof(*s->exp_buffer), alloc_fail); - FF_ALLOC_OR_GOTO(avctx, s->grouped_exp_buffer, AC3_MAX_BLOCKS * channels * - 128 * sizeof(*s->grouped_exp_buffer), alloc_fail); - FF_ALLOC_OR_GOTO(avctx, s->psd_buffer, AC3_MAX_BLOCKS * channels * - AC3_MAX_COEFS * sizeof(*s->psd_buffer), alloc_fail); - FF_ALLOC_OR_GOTO(avctx, s->band_psd_buffer, AC3_MAX_BLOCKS * channels * - 64 * sizeof(*s->band_psd_buffer), alloc_fail); - FF_ALLOC_OR_GOTO(avctx, s->mask_buffer, AC3_MAX_BLOCKS * channels * - 64 * sizeof(*s->mask_buffer), alloc_fail); - FF_ALLOC_OR_GOTO(avctx, s->qmant_buffer, AC3_MAX_BLOCKS * channels * - AC3_MAX_COEFS * sizeof(*s->qmant_buffer), alloc_fail); + FF_ALLOC_OR_GOTO(avctx, s->bap_buffer, total_coefs * + sizeof(*s->bap_buffer), alloc_fail); + FF_ALLOC_OR_GOTO(avctx, s->bap1_buffer, total_coefs * + sizeof(*s->bap1_buffer), alloc_fail); + FF_ALLOCZ_OR_GOTO(avctx, s->mdct_coef_buffer, total_coefs * + sizeof(*s->mdct_coef_buffer), alloc_fail); + FF_ALLOC_OR_GOTO(avctx, s->exp_buffer, total_coefs * + sizeof(*s->exp_buffer), alloc_fail); + FF_ALLOC_OR_GOTO(avctx, s->grouped_exp_buffer, channel_blocks * 128 * + sizeof(*s->grouped_exp_buffer), alloc_fail); + FF_ALLOC_OR_GOTO(avctx, s->psd_buffer, total_coefs * + sizeof(*s->psd_buffer), alloc_fail); + FF_ALLOC_OR_GOTO(avctx, s->band_psd_buffer, channel_blocks * 64 * + sizeof(*s->band_psd_buffer), alloc_fail); + FF_ALLOC_OR_GOTO(avctx, s->mask_buffer, channel_blocks * 64 * + sizeof(*s->mask_buffer), alloc_fail); + FF_ALLOC_OR_GOTO(avctx, s->qmant_buffer, total_coefs * + sizeof(*s->qmant_buffer), alloc_fail); if (s->cpl_enabled) { - FF_ALLOC_OR_GOTO(avctx, s->cpl_coord_exp_buffer, AC3_MAX_BLOCKS * channels * - 16 * sizeof(*s->cpl_coord_exp_buffer), alloc_fail); - FF_ALLOC_OR_GOTO(avctx, s->cpl_coord_mant_buffer, AC3_MAX_BLOCKS * channels * - 16 * sizeof(*s->cpl_coord_mant_buffer), alloc_fail); + FF_ALLOC_OR_GOTO(avctx, s->cpl_coord_exp_buffer, channel_blocks * 16 * + sizeof(*s->cpl_coord_exp_buffer), alloc_fail); + FF_ALLOC_OR_GOTO(avctx, s->cpl_coord_mant_buffer, channel_blocks * 16 * + 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]; FF_ALLOCZ_OR_GOTO(avctx, block->mdct_coef, channels * sizeof(*block->mdct_coef), alloc_fail); @@ -2183,23 +2212,23 @@ static av_cold int allocate_buffers(AC3EncodeContext *s) } /* arrangement: channel, block, coeff */ - block->exp[ch] = &s->exp_buffer [AC3_MAX_COEFS * (AC3_MAX_BLOCKS * ch + blk)]; - block->mdct_coef[ch] = &s->mdct_coef_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 * (s->num_blocks * ch + blk)]; } } if (!s->fixed_point) { - FF_ALLOCZ_OR_GOTO(avctx, s->fixed_coef_buffer, AC3_MAX_BLOCKS * channels * - AC3_MAX_COEFS * sizeof(*s->fixed_coef_buffer), alloc_fail); - for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) { + FF_ALLOCZ_OR_GOTO(avctx, s->fixed_coef_buffer, total_coefs * + sizeof(*s->fixed_coef_buffer), alloc_fail); + for (blk = 0; blk < s->num_blocks; blk++) { AC3Block *block = &s->blocks[blk]; FF_ALLOCZ_OR_GOTO(avctx, block->fixed_coef, channels * sizeof(*block->fixed_coef), alloc_fail); 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 { - for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) { + for (blk = 0; blk < s->num_blocks; blk++) { AC3Block *block = &s->blocks[blk]; FF_ALLOCZ_OR_GOTO(avctx, block->fixed_coef, channels * sizeof(*block->fixed_coef), alloc_fail); @@ -2226,14 +2255,14 @@ av_cold int ff_ac3_encode_init(AVCodecContext *avctx) s->eac3 = avctx->codec_id == CODEC_ID_EAC3; - avctx->frame_size = AC3_FRAME_SIZE; - ff_ac3_common_init(); ret = validate_options(s); if (ret) return ret; + avctx->frame_size = AC3_BLOCK_SIZE * s->num_blocks; + s->bitstream_mode = avctx->audio_service_type; if (s->bitstream_mode == AV_AUDIO_SERVICE_TYPE_KARAOKE) s->bitstream_mode = 0x7; diff --git a/libavcodec/ac3enc.h b/libavcodec/ac3enc.h index a4a8fd432..407e751b4 100644 --- a/libavcodec/ac3enc.h +++ b/libavcodec/ac3enc.h @@ -151,6 +151,8 @@ typedef struct AC3EncodeContext { int bit_rate; ///< target bit rate, in bits-per-second 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; ///< current frame size in bytes int frame_size_code; ///< frame size code (frmsizecod) diff --git a/libavcodec/ac3enc_fixed.c b/libavcodec/ac3enc_fixed.c index ed8992ebf..508ecb1ef 100644 --- a/libavcodec/ac3enc_fixed.c +++ b/libavcodec/ac3enc_fixed.c @@ -93,7 +93,7 @@ static void scale_coefficients(AC3EncodeContext *s) { int blk, ch; - for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) { + for (blk = 0; blk < s->num_blocks; blk++) { AC3Block *block = &s->blocks[blk]; for (ch = 1; ch <= s->channels; ch++) { s->ac3dsp.ac3_rshift_int32(block->mdct_coef[ch], AC3_MAX_COEFS, diff --git a/libavcodec/ac3enc_float.c b/libavcodec/ac3enc_float.c index 776d185fa..9f691a1e1 100644 --- a/libavcodec/ac3enc_float.c +++ b/libavcodec/ac3enc_float.c @@ -103,7 +103,7 @@ static int normalize_samples(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->mdct_coef_buffer + chan_size, chan_size * s->channels); diff --git a/libavcodec/ac3enc_template.c b/libavcodec/ac3enc_template.c index 9b9151b3e..c4e2a121b 100644 --- a/libavcodec/ac3enc_template.c +++ b/libavcodec/ac3enc_template.c @@ -79,13 +79,13 @@ static void deinterleave_input_samples(AC3EncodeContext *s, int sinc; /* 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])); /* deinterleave */ sinc = s->channels; 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; sptr += sinc; } @@ -103,7 +103,7 @@ static void apply_mdct(AC3EncodeContext *s) int blk, 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]; const SampleType *input_samples = &s->planar_samples[ch][blk * AC3_BLOCK_SIZE]; @@ -159,7 +159,7 @@ static void apply_channel_coupling(AC3EncodeContext *s) cpl_start = FFMIN(256, cpl_start + num_cpl_coefs) - num_cpl_coefs; /* 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]; CoefType *cpl_coef = &block->mdct_coef[CPL_CH][cpl_start]; if (!block->cpl_in_use) @@ -188,7 +188,7 @@ static void apply_channel_coupling(AC3EncodeContext *s) while (i < s->cpl_end_freq) { int band_size = s->cpl_band_sizes[bnd]; 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]; if (!block->cpl_in_use || (ch > CPL_CH && !block->channel_in_cpl[ch])) continue; @@ -203,7 +203,7 @@ static void apply_channel_coupling(AC3EncodeContext *s) } /* 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 *block0 = blk ? &s->blocks[blk-1] : NULL; int new_coords = 0; @@ -261,7 +261,7 @@ static void apply_channel_coupling(AC3EncodeContext *s) coordinates in successive blocks */ for (bnd = 0; bnd < s->num_cpl_bands; bnd++) { blk = 0; - while (blk < AC3_MAX_BLOCKS) { + while (blk < s->num_blocks) { int blk1; CoefSumType energy_cpl; AC3Block *block = &s->blocks[blk]; @@ -273,7 +273,7 @@ static void apply_channel_coupling(AC3EncodeContext *s) energy_cpl = energy[blk][CPL_CH][bnd]; 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) energy_cpl += energy[blk1][CPL_CH][bnd]; blk1++; @@ -285,7 +285,7 @@ static void apply_channel_coupling(AC3EncodeContext *s) continue; energy_ch = energy[blk][ch][bnd]; 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) energy_ch += energy[blk1][ch][bnd]; blk1++; @@ -297,7 +297,7 @@ static void apply_channel_coupling(AC3EncodeContext *s) } /* 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]; if (!block->cpl_in_use || !block->new_cpl_coords) continue; @@ -362,7 +362,7 @@ static void compute_rematrixing_strategy(AC3EncodeContext *s) if (s->channel_mode != AC3_CHMODE_STEREO) return; - for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) { + for (blk = 0; blk < s->num_blocks; blk++) { block = &s->blocks[blk]; block->new_rematrixing_strategy = !blk; @@ -440,7 +440,7 @@ int AC3_NAME(encode_frame)(AVCodecContext *avctx, unsigned char *frame, scale_coefficients(s); 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; ff_ac3_compute_coupling_strategy(s); diff --git a/libavcodec/eac3enc.c b/libavcodec/eac3enc.c index 09fa80fcb..038aa2a23 100644 --- a/libavcodec/eac3enc.c +++ b/libavcodec/eac3enc.c @@ -63,6 +63,11 @@ void ff_eac3_get_frame_exp_strategy(AC3EncodeContext *s) { int ch; + if (s->num_blocks < 6) { + s->use_frame_exp_strategy = 0; + return; + } + s->use_frame_exp_strategy = 1; for (ch = !s->cpl_on; ch <= s->fbw_channels; ch++) { 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) /* set first cpl coords */ for (ch = 1; ch <= s->fbw_channels; ch++) 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]; for (ch = 1; ch <= s->fbw_channels; ch++) { if (block->channel_in_cpl[ch]) { @@ -104,7 +109,7 @@ void ff_eac3_set_cpl_states(AC3EncodeContext *s) } /* 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]; if (block->cpl_in_use) { block->new_cpl_leak = 2; @@ -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 */ } else { 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, 1, s->lfe_on); /* LFE channel indicator */ @@ -141,11 +146,15 @@ void ff_eac3_output_frame_header(AC3EncodeContext *s) /* TODO: mixing metadata */ put_bits(&s->pb, 1, 0); /* no 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 */ /* 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, 0); /* aht enabled = no */ + } 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); /* block switch syntax enabled = no */ @@ -158,7 +167,7 @@ void ff_eac3_output_frame_header(AC3EncodeContext *s) /* coupling strategy use flags */ if (s->channel_mode > AC3_CHMODE_MONO) { 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]; put_bits(&s->pb, 1, block->new_cpl_strategy); if (block->new_cpl_strategy) @@ -170,26 +179,31 @@ void ff_eac3_output_frame_header(AC3EncodeContext *s) for (ch = !s->cpl_on; ch <= s->fbw_channels; ch++) put_bits(&s->pb, 5, s->frame_exp_strategy[ch]); } 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++) put_bits(&s->pb, 2, s->exp_strategy[ch][blk]); } 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]); } - /* 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++) { if (s->use_frame_exp_strategy) put_bits(&s->pb, 5, s->frame_exp_strategy[ch]); else put_bits(&s->pb, 5, 0); } + } /* snr offsets */ put_bits(&s->pb, 6, s->coarse_snr_offset); put_bits(&s->pb, 4, s->fine_snr_offset[1]); /* block start info */ - put_bits(&s->pb, 1, 0); + if (s->num_blocks > 1) + put_bits(&s->pb, 1, 0); } -- 2.11.0