|
|
|
@ -746,6 +746,109 @@ static void decode_band_structure(GetBitContext *gbc, int blk, int eac3, |
|
|
|
|
memcpy(band_sizes, bnd_sz, n_bands); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static inline int spx_strategy(AC3DecodeContext *s, int blk) |
|
|
|
|
{ |
|
|
|
|
GetBitContext *bc = &s->gbc; |
|
|
|
|
int fbw_channels = s->fbw_channels; |
|
|
|
|
int dst_start_freq, dst_end_freq, src_start_freq, |
|
|
|
|
start_subband, end_subband, ch; |
|
|
|
|
|
|
|
|
|
/* determine which channels use spx */ |
|
|
|
|
if (s->channel_mode == AC3_CHMODE_MONO) { |
|
|
|
|
s->channel_uses_spx[1] = 1; |
|
|
|
|
} else { |
|
|
|
|
for (ch = 1; ch <= fbw_channels; ch++) |
|
|
|
|
s->channel_uses_spx[ch] = get_bits1(bc); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* get the frequency bins of the spx copy region and the spx start
|
|
|
|
|
and end subbands */ |
|
|
|
|
dst_start_freq = get_bits(bc, 2); |
|
|
|
|
start_subband = get_bits(bc, 3) + 2; |
|
|
|
|
if (start_subband > 7) |
|
|
|
|
start_subband += start_subband - 7; |
|
|
|
|
end_subband = get_bits(bc, 3) + 5; |
|
|
|
|
if (end_subband > 7) |
|
|
|
|
end_subband += end_subband - 7; |
|
|
|
|
dst_start_freq = dst_start_freq * 12 + 25; |
|
|
|
|
src_start_freq = start_subband * 12 + 25; |
|
|
|
|
dst_end_freq = end_subband * 12 + 25; |
|
|
|
|
|
|
|
|
|
/* check validity of spx ranges */ |
|
|
|
|
if (start_subband >= end_subband) { |
|
|
|
|
av_log(s->avctx, AV_LOG_ERROR, "invalid spectral extension " |
|
|
|
|
"range (%d >= %d)\n", start_subband, end_subband); |
|
|
|
|
return AVERROR_INVALIDDATA; |
|
|
|
|
} |
|
|
|
|
if (dst_start_freq >= src_start_freq) { |
|
|
|
|
av_log(s->avctx, AV_LOG_ERROR, "invalid spectral extension " |
|
|
|
|
"copy start bin (%d >= %d)\n", dst_start_freq, src_start_freq); |
|
|
|
|
return AVERROR_INVALIDDATA; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
s->spx_dst_start_freq = dst_start_freq; |
|
|
|
|
s->spx_src_start_freq = src_start_freq; |
|
|
|
|
s->spx_dst_end_freq = dst_end_freq; |
|
|
|
|
|
|
|
|
|
decode_band_structure(bc, blk, s->eac3, 0, |
|
|
|
|
start_subband, end_subband, |
|
|
|
|
ff_eac3_default_spx_band_struct, |
|
|
|
|
&s->num_spx_bands, |
|
|
|
|
s->spx_band_sizes); |
|
|
|
|
|
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static inline void spx_coordinates(AC3DecodeContext *s) |
|
|
|
|
{ |
|
|
|
|
GetBitContext *bc = &s->gbc; |
|
|
|
|
int fbw_channels = s->fbw_channels; |
|
|
|
|
int ch, bnd; |
|
|
|
|
|
|
|
|
|
for (ch = 1; ch <= fbw_channels; ch++) { |
|
|
|
|
if (s->channel_uses_spx[ch]) { |
|
|
|
|
if (s->first_spx_coords[ch] || get_bits1(bc)) { |
|
|
|
|
float spx_blend; |
|
|
|
|
int bin, master_spx_coord; |
|
|
|
|
|
|
|
|
|
s->first_spx_coords[ch] = 0; |
|
|
|
|
spx_blend = get_bits(bc, 5) * (1.0f / 32); |
|
|
|
|
master_spx_coord = get_bits(bc, 2) * 3; |
|
|
|
|
|
|
|
|
|
bin = s->spx_src_start_freq; |
|
|
|
|
for (bnd = 0; bnd < s->num_spx_bands; bnd++) { |
|
|
|
|
int bandsize; |
|
|
|
|
int spx_coord_exp, spx_coord_mant; |
|
|
|
|
float nratio, sblend, nblend, spx_coord; |
|
|
|
|
|
|
|
|
|
/* calculate blending factors */ |
|
|
|
|
bandsize = s->spx_band_sizes[bnd]; |
|
|
|
|
nratio = ((float)((bin + (bandsize >> 1))) / s->spx_dst_end_freq) - spx_blend; |
|
|
|
|
nratio = av_clipf(nratio, 0.0f, 1.0f); |
|
|
|
|
nblend = sqrtf(3.0f * nratio); // noise is scaled by sqrt(3)
|
|
|
|
|
// to give unity variance
|
|
|
|
|
sblend = sqrtf(1.0f - nratio); |
|
|
|
|
bin += bandsize; |
|
|
|
|
|
|
|
|
|
/* decode spx coordinates */ |
|
|
|
|
spx_coord_exp = get_bits(bc, 4); |
|
|
|
|
spx_coord_mant = get_bits(bc, 2); |
|
|
|
|
if (spx_coord_exp == 15) spx_coord_mant <<= 1; |
|
|
|
|
else spx_coord_mant += 4; |
|
|
|
|
spx_coord_mant <<= (25 - spx_coord_exp - master_spx_coord); |
|
|
|
|
spx_coord = spx_coord_mant * (1.0f / (1 << 23)); |
|
|
|
|
|
|
|
|
|
/* multiply noise and signal blending factors by spx coordinate */ |
|
|
|
|
s->spx_noise_blend [ch][bnd] = nblend * spx_coord; |
|
|
|
|
s->spx_signal_blend[ch][bnd] = sblend * spx_coord; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
|
s->first_spx_coords[ch] = 1; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Decode a single audio block from the AC-3 bitstream. |
|
|
|
|
*/ |
|
|
|
@ -753,7 +856,7 @@ static int decode_audio_block(AC3DecodeContext *s, int blk) |
|
|
|
|
{ |
|
|
|
|
int fbw_channels = s->fbw_channels; |
|
|
|
|
int channel_mode = s->channel_mode; |
|
|
|
|
int i, bnd, seg, ch; |
|
|
|
|
int i, bnd, seg, ch, ret; |
|
|
|
|
int different_transforms; |
|
|
|
|
int downmix_output; |
|
|
|
|
int cpl_in_use; |
|
|
|
@ -797,51 +900,8 @@ static int decode_audio_block(AC3DecodeContext *s, int blk) |
|
|
|
|
if (s->eac3 && (!blk || get_bits1(gbc))) { |
|
|
|
|
s->spx_in_use = get_bits1(gbc); |
|
|
|
|
if (s->spx_in_use) { |
|
|
|
|
int dst_start_freq, dst_end_freq, src_start_freq, |
|
|
|
|
start_subband, end_subband; |
|
|
|
|
|
|
|
|
|
/* determine which channels use spx */ |
|
|
|
|
if (s->channel_mode == AC3_CHMODE_MONO) { |
|
|
|
|
s->channel_uses_spx[1] = 1; |
|
|
|
|
} else { |
|
|
|
|
for (ch = 1; ch <= fbw_channels; ch++) |
|
|
|
|
s->channel_uses_spx[ch] = get_bits1(gbc); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* get the frequency bins of the spx copy region and the spx start
|
|
|
|
|
and end subbands */ |
|
|
|
|
dst_start_freq = get_bits(gbc, 2); |
|
|
|
|
start_subband = get_bits(gbc, 3) + 2; |
|
|
|
|
if (start_subband > 7) |
|
|
|
|
start_subband += start_subband - 7; |
|
|
|
|
end_subband = get_bits(gbc, 3) + 5; |
|
|
|
|
if (end_subband > 7) |
|
|
|
|
end_subband += end_subband - 7; |
|
|
|
|
dst_start_freq = dst_start_freq * 12 + 25; |
|
|
|
|
src_start_freq = start_subband * 12 + 25; |
|
|
|
|
dst_end_freq = end_subband * 12 + 25; |
|
|
|
|
|
|
|
|
|
/* check validity of spx ranges */ |
|
|
|
|
if (start_subband >= end_subband) { |
|
|
|
|
av_log(s->avctx, AV_LOG_ERROR, "invalid spectral extension " |
|
|
|
|
"range (%d >= %d)\n", start_subband, end_subband); |
|
|
|
|
return AVERROR_INVALIDDATA; |
|
|
|
|
} |
|
|
|
|
if (dst_start_freq >= src_start_freq) { |
|
|
|
|
av_log(s->avctx, AV_LOG_ERROR, "invalid spectral extension " |
|
|
|
|
"copy start bin (%d >= %d)\n", dst_start_freq, src_start_freq); |
|
|
|
|
return AVERROR_INVALIDDATA; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
s->spx_dst_start_freq = dst_start_freq; |
|
|
|
|
s->spx_src_start_freq = src_start_freq; |
|
|
|
|
s->spx_dst_end_freq = dst_end_freq; |
|
|
|
|
|
|
|
|
|
decode_band_structure(gbc, blk, s->eac3, 0, |
|
|
|
|
start_subband, end_subband, |
|
|
|
|
ff_eac3_default_spx_band_struct, |
|
|
|
|
&s->num_spx_bands, |
|
|
|
|
s->spx_band_sizes); |
|
|
|
|
if ((ret = spx_strategy(s, blk)) < 0) |
|
|
|
|
return ret; |
|
|
|
|
} else { |
|
|
|
|
for (ch = 1; ch <= fbw_channels; ch++) { |
|
|
|
|
s->channel_uses_spx[ch] = 0; |
|
|
|
@ -851,50 +911,8 @@ static int decode_audio_block(AC3DecodeContext *s, int blk) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* spectral extension coordinates */ |
|
|
|
|
if (s->spx_in_use) { |
|
|
|
|
for (ch = 1; ch <= fbw_channels; ch++) { |
|
|
|
|
if (s->channel_uses_spx[ch]) { |
|
|
|
|
if (s->first_spx_coords[ch] || get_bits1(gbc)) { |
|
|
|
|
float spx_blend; |
|
|
|
|
int bin, master_spx_coord; |
|
|
|
|
|
|
|
|
|
s->first_spx_coords[ch] = 0; |
|
|
|
|
spx_blend = get_bits(gbc, 5) * (1.0f/32); |
|
|
|
|
master_spx_coord = get_bits(gbc, 2) * 3; |
|
|
|
|
|
|
|
|
|
bin = s->spx_src_start_freq; |
|
|
|
|
for (bnd = 0; bnd < s->num_spx_bands; bnd++) { |
|
|
|
|
int bandsize; |
|
|
|
|
int spx_coord_exp, spx_coord_mant; |
|
|
|
|
float nratio, sblend, nblend, spx_coord; |
|
|
|
|
|
|
|
|
|
/* calculate blending factors */ |
|
|
|
|
bandsize = s->spx_band_sizes[bnd]; |
|
|
|
|
nratio = ((float)((bin + (bandsize >> 1))) / s->spx_dst_end_freq) - spx_blend; |
|
|
|
|
nratio = av_clipf(nratio, 0.0f, 1.0f); |
|
|
|
|
nblend = sqrtf(3.0f * nratio); // noise is scaled by sqrt(3)
|
|
|
|
|
// to give unity variance
|
|
|
|
|
sblend = sqrtf(1.0f - nratio); |
|
|
|
|
bin += bandsize; |
|
|
|
|
|
|
|
|
|
/* decode spx coordinates */ |
|
|
|
|
spx_coord_exp = get_bits(gbc, 4); |
|
|
|
|
spx_coord_mant = get_bits(gbc, 2); |
|
|
|
|
if (spx_coord_exp == 15) spx_coord_mant <<= 1; |
|
|
|
|
else spx_coord_mant += 4; |
|
|
|
|
spx_coord_mant <<= (25 - spx_coord_exp - master_spx_coord); |
|
|
|
|
spx_coord = spx_coord_mant * (1.0f / (1 << 23)); |
|
|
|
|
|
|
|
|
|
/* multiply noise and signal blending factors by spx coordinate */ |
|
|
|
|
s->spx_noise_blend [ch][bnd] = nblend * spx_coord; |
|
|
|
|
s->spx_signal_blend[ch][bnd] = sblend * spx_coord; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
|
s->first_spx_coords[ch] = 1; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
if (s->spx_in_use) |
|
|
|
|
spx_coordinates(s); |
|
|
|
|
|
|
|
|
|
/* coupling strategy */ |
|
|
|
|
if (s->eac3 ? s->cpl_strategy_exists[blk] : get_bits1(gbc)) { |
|
|
|
|