ffmpeg | branch: master | Clément Bœsch <u...@pkh.me> | Wed Mar 15 21:43:59 2017 +0100| [7c4dbd1df985b171252d0d8deaf3c87c82d710da] | committer: Clément Bœsch
Merge commit 'a5ebe5d1217942238c641c83b24ef1106e53934a' * commit 'a5ebe5d1217942238c641c83b24ef1106e53934a': ac3dec: Split spx-specific code from decode_audio_block() Merged-by: Clément Bœsch <u...@pkh.me> > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=7c4dbd1df985b171252d0d8deaf3c87c82d710da --- libavcodec/ac3dec.c | 261 ++++++++++++++++++++++++++++------------------------ 1 file changed, 139 insertions(+), 122 deletions(-) diff --git a/libavcodec/ac3dec.c b/libavcodec/ac3dec.c index 4499160..bd17b69 100644 --- a/libavcodec/ac3dec.c +++ b/libavcodec/ac3dec.c @@ -801,6 +801,140 @@ 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 USE_FIXED + s->spx_dst_end_freq = end_freq_inv_tab[end_subband-5]; +#endif + 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; + if (!USE_FIXED) + 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)) { + INTFLOAT spx_blend; + int bin, master_spx_coord; + + s->first_spx_coords[ch] = 0; + spx_blend = AC3_SPX_BLEND(get_bits(bc, 5)); + 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 = s->spx_band_sizes[bnd]; + int spx_coord_exp, spx_coord_mant; + INTFLOAT nratio, sblend, nblend; +#if USE_FIXED + /* calculate blending factors */ + int64_t accu = ((bin << 23) + (bandsize << 22)) + * (int64_t)s->spx_dst_end_freq; + nratio = (int)(accu >> 32); + nratio -= spx_blend << 18; + + if (nratio < 0) { + nblend = 0; + sblend = 0x800000; + } else if (nratio > 0x7fffff) { + nblend = 14529495; // sqrt(3) in FP.23 + sblend = 0; + } else { + nblend = fixed_sqrt(nratio, 23); + accu = (int64_t)nblend * 1859775393; + nblend = (int)((accu + (1<<29)) >> 30); + sblend = fixed_sqrt(0x800000 - nratio, 23); + } +#else + float spx_coord; + + /* calculate blending factors */ + 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); +#endif + 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); + + /* multiply noise and signal blending factors by spx coordinate */ +#if USE_FIXED + accu = (int64_t)nblend * spx_coord_mant; + s->spx_noise_blend[ch][bnd] = (int)((accu + (1<<22)) >> 23); + accu = (int64_t)sblend * spx_coord_mant; + s->spx_signal_blend[ch][bnd] = (int)((accu + (1<<22)) >> 23); +#else + spx_coord = spx_coord_mant * (1.0f / (1 << 23)); + s->spx_noise_blend [ch][bnd] = nblend * spx_coord; + s->spx_signal_blend[ch][bnd] = sblend * spx_coord; +#endif + } + } + } else { + s->first_spx_coords[ch] = 1; + } + } +} + /** * Decode a single audio block from the AC-3 bitstream. */ @@ -808,7 +942,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; @@ -853,55 +987,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 USE_FIXED - s->spx_dst_end_freq = end_freq_inv_tab[end_subband-5]; -#endif - 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; - if (!USE_FIXED) - 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; } } if (!s->eac3 || !s->spx_in_use) { @@ -913,78 +1000,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)) { - INTFLOAT spx_blend; - int bin, master_spx_coord; - - s->first_spx_coords[ch] = 0; - spx_blend = AC3_SPX_BLEND(get_bits(gbc, 5)); - 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 = s->spx_band_sizes[bnd]; - int spx_coord_exp, spx_coord_mant; - INTFLOAT nratio, sblend, nblend; -#if USE_FIXED - /* calculate blending factors */ - int64_t accu = ((bin << 23) + (bandsize << 22)) - * (int64_t)s->spx_dst_end_freq; - nratio = (int)(accu >> 32); - nratio -= spx_blend << 18; - - if (nratio < 0) { - nblend = 0; - sblend = 0x800000; - } else if (nratio > 0x7fffff) { - nblend = 14529495; // sqrt(3) in FP.23 - sblend = 0; - } else { - nblend = fixed_sqrt(nratio, 23); - accu = (int64_t)nblend * 1859775393; - nblend = (int)((accu + (1<<29)) >> 30); - sblend = fixed_sqrt(0x800000 - nratio, 23); - } -#else - float spx_coord; - - /* calculate blending factors */ - 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); -#endif - 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); - - /* multiply noise and signal blending factors by spx coordinate */ -#if USE_FIXED - accu = (int64_t)nblend * spx_coord_mant; - s->spx_noise_blend[ch][bnd] = (int)((accu + (1<<22)) >> 23); - accu = (int64_t)sblend * spx_coord_mant; - s->spx_signal_blend[ch][bnd] = (int)((accu + (1<<22)) >> 23); -#else - spx_coord = spx_coord_mant * (1.0f / (1 << 23)); - s->spx_noise_blend [ch][bnd] = nblend * spx_coord; - s->spx_signal_blend[ch][bnd] = sblend * spx_coord; -#endif - } - } - } 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)) { ====================================================================== diff --cc libavcodec/ac3dec.c index 4499160,4de7475..bd17b69 --- a/libavcodec/ac3dec.c +++ b/libavcodec/ac3dec.c @@@ -801,6 -746,109 +801,140 @@@ static void decode_band_structure(GetBi 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 USE_FIXED ++ s->spx_dst_end_freq = end_freq_inv_tab[end_subband-5]; ++#endif + 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; ++ if (!USE_FIXED) ++ 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; ++ INTFLOAT spx_blend; + int bin, master_spx_coord; + + s->first_spx_coords[ch] = 0; - spx_blend = get_bits(bc, 5) * (1.0f / 32); ++ spx_blend = AC3_SPX_BLEND(get_bits(bc, 5)); + 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 bandsize = s->spx_band_sizes[bnd]; + int spx_coord_exp, spx_coord_mant; - float nratio, sblend, nblend, spx_coord; ++ INTFLOAT nratio, sblend, nblend; ++#if USE_FIXED ++ /* calculate blending factors */ ++ int64_t accu = ((bin << 23) + (bandsize << 22)) ++ * (int64_t)s->spx_dst_end_freq; ++ nratio = (int)(accu >> 32); ++ nratio -= spx_blend << 18; ++ ++ if (nratio < 0) { ++ nblend = 0; ++ sblend = 0x800000; ++ } else if (nratio > 0x7fffff) { ++ nblend = 14529495; // sqrt(3) in FP.23 ++ sblend = 0; ++ } else { ++ nblend = fixed_sqrt(nratio, 23); ++ accu = (int64_t)nblend * 1859775393; ++ nblend = (int)((accu + (1<<29)) >> 30); ++ sblend = fixed_sqrt(0x800000 - nratio, 23); ++ } ++#else ++ float 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); ++#endif + 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 */ ++#if USE_FIXED ++ accu = (int64_t)nblend * spx_coord_mant; ++ s->spx_noise_blend[ch][bnd] = (int)((accu + (1<<22)) >> 23); ++ accu = (int64_t)sblend * spx_coord_mant; ++ s->spx_signal_blend[ch][bnd] = (int)((accu + (1<<22)) >> 23); ++#else ++ spx_coord = spx_coord_mant * (1.0f / (1 << 23)); + s->spx_noise_blend [ch][bnd] = nblend * spx_coord; + s->spx_signal_blend[ch][bnd] = sblend * spx_coord; ++#endif + } + } + } else { + s->first_spx_coords[ch] = 1; + } + } + } + /** * Decode a single audio block from the AC-3 bitstream. */ @@@ -853,62 -900,13 +987,15 @@@ static int decode_audio_block(AC3Decode 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 USE_FIXED - s->spx_dst_end_freq = end_freq_inv_tab[end_subband-5]; - #endif - 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; - if (!USE_FIXED) - 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; - s->first_spx_coords[ch] = 1; - } + } + } + if (!s->eac3 || !s->spx_in_use) { + s->spx_in_use = 0; + for (ch = 1; ch <= fbw_channels; ch++) { + s->channel_uses_spx[ch] = 0; + s->first_spx_coords[ch] = 1; } } _______________________________________________ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog