From d55ad59a8a67b73f3370ee01efd0051fbffe3577 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Fri, 5 Aug 2011 16:00:18 -0400 Subject: ac3enc: separate exponent bit counting from exponent grouping. Move bit counting to the bit allocation function. Move exponent grouping to after bit allocation. This will allow for adjustment of bandwidth parameters during bit allocation without having to do exponent grouping multiple times. --- libavcodec/ac3enc.c | 40 ++++++++++++++++++++++++++++++++-------- 1 file changed, 32 insertions(+), 8 deletions(-) (limited to 'libavcodec/ac3enc.c') diff --git a/libavcodec/ac3enc.c b/libavcodec/ac3enc.c index c138f99207..d454654c00 100644 --- a/libavcodec/ac3enc.c +++ b/libavcodec/ac3enc.c @@ -526,20 +526,47 @@ static void encode_exponents(AC3EncodeContext *s) } +/** + * Count exponent bits based on bandwidth, coupling, and exponent strategies. + */ +static int count_exponent_bits(AC3EncodeContext *s) +{ + int blk, ch; + int nb_groups, bit_count; + + bit_count = 0; + 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]; + int cpl = (ch == CPL_CH); + int nb_coefs = block->end_freq[ch] - s->start_freq[ch]; + + if (exp_strategy == EXP_REUSE) + continue; + + nb_groups = exponent_group_tab[cpl][exp_strategy-1][nb_coefs]; + bit_count += 4 + (nb_groups * 7); + } + } + + return bit_count; +} + + /** * Group exponents. * 3 delta-encoded exponents are in each 7-bit group. The number of groups * varies depending on exponent strategy and bandwidth. */ -static void group_exponents(AC3EncodeContext *s) +void ff_ac3_group_exponents(AC3EncodeContext *s) { int blk, ch, i, cpl; - int group_size, nb_groups, bit_count; + int group_size, nb_groups; uint8_t *p; int delta0, delta1, delta2; int exp0, exp1; - bit_count = 0; for (blk = 0; blk < s->num_blocks; blk++) { AC3Block *block = &s->blocks[blk]; for (ch = !block->cpl_in_use; ch <= s->channels; ch++) { @@ -549,7 +576,6 @@ static void group_exponents(AC3EncodeContext *s) cpl = (ch == CPL_CH); group_size = exp_strategy + (exp_strategy == EXP_D45); nb_groups = exponent_group_tab[cpl][exp_strategy-1][block->end_freq[ch]-s->start_freq[ch]]; - bit_count += 4 + (nb_groups * 7); p = block->exp[ch] + s->start_freq[ch] - cpl; /* DC exponent */ @@ -581,8 +607,6 @@ static void group_exponents(AC3EncodeContext *s) } } } - - s->exponent_bits = bit_count; } @@ -599,8 +623,6 @@ void ff_ac3_process_exponents(AC3EncodeContext *s) encode_exponents(s); - group_exponents(s); - emms_c(); } @@ -1095,6 +1117,8 @@ int ff_ac3_compute_bit_allocation(AC3EncodeContext *s) { count_frame_bits(s); + s->exponent_bits = count_exponent_bits(s); + bit_alloc_masking(s); return cbr_bit_allocation(s); -- cgit v1.2.3 From c3d63262fe61a8e219c4b69c61af6e0c9d49be2d Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Fri, 5 Aug 2011 16:28:39 -0400 Subject: ac3enc: allow new coupling coordinates to be sent independently for each channel. --- libavcodec/ac3enc.c | 10 ++++----- libavcodec/ac3enc.h | 2 +- libavcodec/ac3enc_template.c | 50 +++++++++++++++++--------------------------- libavcodec/eac3enc.c | 2 +- 4 files changed, 26 insertions(+), 38 deletions(-) (limited to 'libavcodec/ac3enc.c') diff --git a/libavcodec/ac3enc.c b/libavcodec/ac3enc.c index d454654c00..291a60d2da 100644 --- a/libavcodec/ac3enc.c +++ b/libavcodec/ac3enc.c @@ -864,9 +864,9 @@ static void count_frame_bits(AC3EncodeContext *s) if (block->cpl_in_use) { for (ch = 1; ch <= s->fbw_channels; ch++) { if (block->channel_in_cpl[ch]) { - if (!s->eac3 || block->new_cpl_coords != 2) + if (!s->eac3 || block->new_cpl_coords[ch] != 2) frame_bits++; - if (block->new_cpl_coords) { + if (block->new_cpl_coords[ch]) { frame_bits += 2; frame_bits += (4 + 4) * s->num_cpl_bands; } @@ -1394,9 +1394,9 @@ static void output_audio_block(AC3EncodeContext *s, int blk) if (block->cpl_in_use) { for (ch = 1; ch <= s->fbw_channels; ch++) { if (block->channel_in_cpl[ch]) { - if (!s->eac3 || block->new_cpl_coords != 2) - put_bits(&s->pb, 1, block->new_cpl_coords); - if (block->new_cpl_coords) { + if (!s->eac3 || block->new_cpl_coords[ch] != 2) + put_bits(&s->pb, 1, block->new_cpl_coords[ch]); + if (block->new_cpl_coords[ch]) { put_bits(&s->pb, 2, block->cpl_master_exp[ch]); for (bnd = 0; bnd < s->num_cpl_bands; bnd++) { put_bits(&s->pb, 4, block->cpl_coord_exp [ch][bnd]); diff --git a/libavcodec/ac3enc.h b/libavcodec/ac3enc.h index c1e69b101f..98e2432cc5 100644 --- a/libavcodec/ac3enc.h +++ b/libavcodec/ac3enc.h @@ -123,7 +123,7 @@ typedef struct AC3Block { int cpl_in_use; ///< coupling in use for this block (cplinu) uint8_t channel_in_cpl[AC3_MAX_CHANNELS]; ///< channel in coupling (chincpl) int num_cpl_channels; ///< number of channels in coupling - uint8_t new_cpl_coords; ///< send new coupling coordinates (cplcoe) + uint8_t new_cpl_coords[AC3_MAX_CHANNELS]; ///< send new coupling coordinates (cplcoe) uint8_t cpl_master_exp[AC3_MAX_CHANNELS]; ///< coupling coord master exponents (mstrcplco) int new_snr_offsets; ///< send new SNR offsets int new_cpl_leak; ///< send new coupling leak info diff --git a/libavcodec/ac3enc_template.c b/libavcodec/ac3enc_template.c index dd1e48d1f8..4b0c768e63 100644 --- a/libavcodec/ac3enc_template.c +++ b/libavcodec/ac3enc_template.c @@ -206,9 +206,10 @@ static void apply_channel_coupling(AC3EncodeContext *s) 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; CoefSumType coord_diff[AC3_MAX_CHANNELS] = {0,}; + memset(block->new_cpl_coords, 0, sizeof(block->new_cpl_coords)); + if (block->cpl_in_use) { /* calculate coupling coordinates for all blocks and calculate the average difference between coordinates in successive blocks */ @@ -233,28 +234,18 @@ static void apply_channel_coupling(AC3EncodeContext *s) * using coupling has changed from the previous block, or the * coordinate difference from the last block for any channel is * greater than a threshold value. */ - if (blk == 0) { - new_coords = 1; - } else if (!block0->cpl_in_use) { - new_coords = 1; + if (blk == 0 || !block0->cpl_in_use) { + for (ch = 1; ch <= s->fbw_channels; ch++) + block->new_cpl_coords[ch] = 1; } else { for (ch = 1; ch <= s->fbw_channels; ch++) { - if (block->channel_in_cpl[ch] && !block0->channel_in_cpl[ch]) { - new_coords = 1; - break; - } - } - if (!new_coords) { - for (ch = 1; ch <= s->fbw_channels; ch++) { - if (block->channel_in_cpl[ch] && coord_diff[ch] > 0.04) { - new_coords = 1; - break; - } + if ((block->channel_in_cpl[ch] && !block0->channel_in_cpl[ch]) || + (block->channel_in_cpl[ch] && coord_diff[ch] > 0.03)) { + block->new_cpl_coords[ch] = 1; } } } } - block->new_cpl_coords = new_coords; } /* calculate final coupling coordinates, taking into account reusing of @@ -262,8 +253,7 @@ static void apply_channel_coupling(AC3EncodeContext *s) for (bnd = 0; bnd < s->num_cpl_bands; bnd++) { blk = 0; while (blk < s->num_blocks) { - int blk1; - CoefSumType energy_cpl; + int av_uninit(blk1); AC3Block *block = &s->blocks[blk]; if (!block->cpl_in_use) { @@ -271,23 +261,18 @@ static void apply_channel_coupling(AC3EncodeContext *s) continue; } - energy_cpl = energy[blk][CPL_CH][bnd]; - blk1 = blk+1; - 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++; - } - for (ch = 1; ch <= s->fbw_channels; ch++) { - CoefType energy_ch; + CoefSumType energy_ch, energy_cpl; if (!block->channel_in_cpl[ch]) continue; + energy_cpl = energy[blk][CPL_CH][bnd]; energy_ch = energy[blk][ch][bnd]; blk1 = blk+1; - while (!s->blocks[blk1].new_cpl_coords && blk1 < s->num_blocks) { - if (s->blocks[blk1].cpl_in_use) + while (!s->blocks[blk1].new_cpl_coords[ch] && blk1 < s->num_blocks) { + if (s->blocks[blk1].cpl_in_use) { + energy_cpl += energy[blk1][CPL_CH][bnd]; energy_ch += energy[blk1][ch][bnd]; + } blk1++; } cpl_coords[blk][ch][bnd] = calc_cpl_coord(energy_ch, energy_cpl); @@ -299,7 +284,7 @@ static void apply_channel_coupling(AC3EncodeContext *s) /* calculate exponents/mantissas for coupling coordinates */ for (blk = 0; blk < s->num_blocks; blk++) { AC3Block *block = &s->blocks[blk]; - if (!block->cpl_in_use || !block->new_cpl_coords) + if (!block->cpl_in_use) continue; clip_coefficients(&s->dsp, cpl_coords[blk][1], s->fbw_channels * 16); @@ -313,6 +298,9 @@ static void apply_channel_coupling(AC3EncodeContext *s) for (ch = 1; ch <= s->fbw_channels; ch++) { int bnd, min_exp, max_exp, master_exp; + if (!block->new_cpl_coords[ch]) + continue; + /* determine master exponent */ min_exp = max_exp = block->cpl_coord_exp[ch][0]; for (bnd = 1; bnd < s->num_cpl_bands; bnd++) { diff --git a/libavcodec/eac3enc.c b/libavcodec/eac3enc.c index 75113b272f..f3b4418896 100644 --- a/libavcodec/eac3enc.c +++ b/libavcodec/eac3enc.c @@ -99,7 +99,7 @@ void ff_eac3_set_cpl_states(AC3EncodeContext *s) for (ch = 1; ch <= s->fbw_channels; ch++) { if (block->channel_in_cpl[ch]) { if (first_cpl_coords[ch]) { - block->new_cpl_coords = 2; + block->new_cpl_coords[ch] = 2; first_cpl_coords[ch] = 0; } } else { -- cgit v1.2.3