Commit c3d63262 authored by Justin Ruggles's avatar Justin Ruggles

ac3enc: allow new coupling coordinates to be sent independently for each

channel.
parent d55ad59a
...@@ -864,9 +864,9 @@ static void count_frame_bits(AC3EncodeContext *s) ...@@ -864,9 +864,9 @@ static void count_frame_bits(AC3EncodeContext *s)
if (block->cpl_in_use) { if (block->cpl_in_use) {
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]) {
if (!s->eac3 || block->new_cpl_coords != 2) if (!s->eac3 || block->new_cpl_coords[ch] != 2)
frame_bits++; frame_bits++;
if (block->new_cpl_coords) { if (block->new_cpl_coords[ch]) {
frame_bits += 2; frame_bits += 2;
frame_bits += (4 + 4) * s->num_cpl_bands; frame_bits += (4 + 4) * s->num_cpl_bands;
} }
...@@ -1394,9 +1394,9 @@ static void output_audio_block(AC3EncodeContext *s, int blk) ...@@ -1394,9 +1394,9 @@ static void output_audio_block(AC3EncodeContext *s, int blk)
if (block->cpl_in_use) { if (block->cpl_in_use) {
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]) {
if (!s->eac3 || block->new_cpl_coords != 2) if (!s->eac3 || block->new_cpl_coords[ch] != 2)
put_bits(&s->pb, 1, block->new_cpl_coords); put_bits(&s->pb, 1, block->new_cpl_coords[ch]);
if (block->new_cpl_coords) { if (block->new_cpl_coords[ch]) {
put_bits(&s->pb, 2, block->cpl_master_exp[ch]); put_bits(&s->pb, 2, block->cpl_master_exp[ch]);
for (bnd = 0; bnd < s->num_cpl_bands; bnd++) { for (bnd = 0; bnd < s->num_cpl_bands; bnd++) {
put_bits(&s->pb, 4, block->cpl_coord_exp [ch][bnd]); put_bits(&s->pb, 4, block->cpl_coord_exp [ch][bnd]);
......
...@@ -123,7 +123,7 @@ typedef struct AC3Block { ...@@ -123,7 +123,7 @@ typedef struct AC3Block {
int cpl_in_use; ///< coupling in use for this block (cplinu) int cpl_in_use; ///< coupling in use for this block (cplinu)
uint8_t channel_in_cpl[AC3_MAX_CHANNELS]; ///< channel in coupling (chincpl) uint8_t channel_in_cpl[AC3_MAX_CHANNELS]; ///< channel in coupling (chincpl)
int num_cpl_channels; ///< number of channels in coupling 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) uint8_t cpl_master_exp[AC3_MAX_CHANNELS]; ///< coupling coord master exponents (mstrcplco)
int new_snr_offsets; ///< send new SNR offsets int new_snr_offsets; ///< send new SNR offsets
int new_cpl_leak; ///< send new coupling leak info int new_cpl_leak; ///< send new coupling leak info
......
...@@ -206,9 +206,10 @@ static void apply_channel_coupling(AC3EncodeContext *s) ...@@ -206,9 +206,10 @@ static void apply_channel_coupling(AC3EncodeContext *s)
for (blk = 0; blk < s->num_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;
CoefSumType coord_diff[AC3_MAX_CHANNELS] = {0,}; CoefSumType coord_diff[AC3_MAX_CHANNELS] = {0,};
memset(block->new_cpl_coords, 0, sizeof(block->new_cpl_coords));
if (block->cpl_in_use) { if (block->cpl_in_use) {
/* calculate coupling coordinates for all blocks and calculate the /* calculate coupling coordinates for all blocks and calculate the
average difference between coordinates in successive blocks */ average difference between coordinates in successive blocks */
...@@ -233,28 +234,18 @@ static void apply_channel_coupling(AC3EncodeContext *s) ...@@ -233,28 +234,18 @@ static void apply_channel_coupling(AC3EncodeContext *s)
* using coupling has changed from the previous block, or the * using coupling has changed from the previous block, or the
* coordinate difference from the last block for any channel is * coordinate difference from the last block for any channel is
* greater than a threshold value. */ * greater than a threshold value. */
if (blk == 0) { if (blk == 0 || !block0->cpl_in_use) {
new_coords = 1; for (ch = 1; ch <= s->fbw_channels; ch++)
} else if (!block0->cpl_in_use) { block->new_cpl_coords[ch] = 1;
new_coords = 1;
} else { } else {
for (ch = 1; ch <= s->fbw_channels; ch++) { for (ch = 1; ch <= s->fbw_channels; ch++) {
if (block->channel_in_cpl[ch] && !block0->channel_in_cpl[ch]) { if ((block->channel_in_cpl[ch] && !block0->channel_in_cpl[ch]) ||
new_coords = 1; (block->channel_in_cpl[ch] && coord_diff[ch] > 0.03)) {
break; block->new_cpl_coords[ch] = 1;
}
}
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;
}
} }
} }
} }
} }
block->new_cpl_coords = new_coords;
} }
/* calculate final coupling coordinates, taking into account reusing of /* calculate final coupling coordinates, taking into account reusing of
...@@ -262,8 +253,7 @@ static void apply_channel_coupling(AC3EncodeContext *s) ...@@ -262,8 +253,7 @@ static void apply_channel_coupling(AC3EncodeContext *s)
for (bnd = 0; bnd < s->num_cpl_bands; bnd++) { for (bnd = 0; bnd < s->num_cpl_bands; bnd++) {
blk = 0; blk = 0;
while (blk < s->num_blocks) { while (blk < s->num_blocks) {
int blk1; int av_uninit(blk1);
CoefSumType energy_cpl;
AC3Block *block = &s->blocks[blk]; AC3Block *block = &s->blocks[blk];
if (!block->cpl_in_use) { if (!block->cpl_in_use) {
...@@ -271,23 +261,18 @@ static void apply_channel_coupling(AC3EncodeContext *s) ...@@ -271,23 +261,18 @@ static void apply_channel_coupling(AC3EncodeContext *s)
continue; 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++) { for (ch = 1; ch <= s->fbw_channels; ch++) {
CoefType energy_ch; CoefSumType energy_ch, energy_cpl;
if (!block->channel_in_cpl[ch]) if (!block->channel_in_cpl[ch])
continue; continue;
energy_cpl = energy[blk][CPL_CH][bnd];
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 < s->num_blocks) { while (!s->blocks[blk1].new_cpl_coords[ch] && 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_ch += energy[blk1][ch][bnd]; energy_ch += energy[blk1][ch][bnd];
}
blk1++; blk1++;
} }
cpl_coords[blk][ch][bnd] = calc_cpl_coord(energy_ch, energy_cpl); cpl_coords[blk][ch][bnd] = calc_cpl_coord(energy_ch, energy_cpl);
...@@ -299,7 +284,7 @@ static void apply_channel_coupling(AC3EncodeContext *s) ...@@ -299,7 +284,7 @@ static void apply_channel_coupling(AC3EncodeContext *s)
/* calculate exponents/mantissas for coupling coordinates */ /* calculate exponents/mantissas for coupling coordinates */
for (blk = 0; blk < s->num_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)
continue; continue;
clip_coefficients(&s->dsp, cpl_coords[blk][1], s->fbw_channels * 16); clip_coefficients(&s->dsp, cpl_coords[blk][1], s->fbw_channels * 16);
...@@ -313,6 +298,9 @@ static void apply_channel_coupling(AC3EncodeContext *s) ...@@ -313,6 +298,9 @@ static void apply_channel_coupling(AC3EncodeContext *s)
for (ch = 1; ch <= s->fbw_channels; ch++) { for (ch = 1; ch <= s->fbw_channels; ch++) {
int bnd, min_exp, max_exp, master_exp; int bnd, min_exp, max_exp, master_exp;
if (!block->new_cpl_coords[ch])
continue;
/* determine master exponent */ /* determine master exponent */
min_exp = max_exp = block->cpl_coord_exp[ch][0]; min_exp = max_exp = block->cpl_coord_exp[ch][0];
for (bnd = 1; bnd < s->num_cpl_bands; bnd++) { for (bnd = 1; bnd < s->num_cpl_bands; bnd++) {
......
...@@ -99,7 +99,7 @@ void ff_eac3_set_cpl_states(AC3EncodeContext *s) ...@@ -99,7 +99,7 @@ void ff_eac3_set_cpl_states(AC3EncodeContext *s)
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]) {
if (first_cpl_coords[ch]) { if (first_cpl_coords[ch]) {
block->new_cpl_coords = 2; block->new_cpl_coords[ch] = 2;
first_cpl_coords[ch] = 0; first_cpl_coords[ch] = 0;
} }
} else { } else {
......
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