eac3_spectral.patch
资源名称:vlc-1.0.5.zip [点击查看]
上传用户:kjfoods
上传日期:2020-07-06
资源大小:29949k
文件大小:20k
源码类别:
midi
开发平台:
Unix_Linux
- diff --git a/libavcodec/ac3dec.c b/libavcodec/ac3dec.c
- index baff415..49d6ea9 100644
- --- a/libavcodec/ac3dec.c
- +++ b/libavcodec/ac3dec.c
- @@ -826,14 +826,105 @@ static int decode_audio_block(AC3DecodeContext *s, int blk)
- /* spectral extension strategy */
- if (s->eac3 && (!blk || get_bits1(gbc))) {
- - if (get_bits1(gbc)) {
- - av_log_missing_feature(s->avctx, "Spectral extension", 1);
- - return -1;
- + s->spx_in_use = get_bits1(gbc);
- + if (s->spx_in_use) {
- + int copy_start, start_subband, end_subband, start_freq, end_freq;
- +
- + /* 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 */
- + copy_start = 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;
- + copy_start = copy_start * 12 + 25;
- + start_freq = start_subband * 12 + 25;
- + 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 -1;
- + }
- + if (copy_start >= start_freq) {
- + av_log(s->avctx, AV_LOG_ERROR, "invalid spectral extension "
- + "copy start bin (%d >= %d)n", copy_start, start_freq);
- + return -1;
- + }
- +
- + s->spx_copy_start_freq = copy_start;
- + s->spx_start_subband = start_subband;
- + s->spx_start_freq = start_freq;
- + s->spx_end_freq = 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);
- + } else {
- + for (ch = 1; ch <= fbw_channels; ch++) {
- + s->channel_uses_spx[ch] = 0;
- + s->first_spx_coords[ch] = 1;
- + }
- }
- - /* TODO: parse spectral extension strategy info */
- }
- - /* TODO: spectral extension coordinates */
- + /* 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_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_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;
- + }
- + }
- + }
- /* coupling strategy */
- if (s->eac3 ? s->cpl_strategy_exists[blk] : get_bits1(gbc)) {
- @@ -870,9 +961,9 @@ static int decode_audio_block(AC3DecodeContext *s, int blk)
- s->phase_flags_in_use = get_bits1(gbc);
- /* coupling frequency range */
- - /* TODO: modify coupling end freq if spectral extension is used */
- cpl_start_subband = get_bits(gbc, 4);
- - cpl_end_subband = get_bits(gbc, 4) + 3;
- + cpl_end_subband = s->spx_in_use ? s->spx_start_subband - 1 :
- + get_bits(gbc, 4) + 3;
- if (cpl_start_subband >= cpl_end_subband) {
- av_log(s->avctx, AV_LOG_ERROR, "invalid coupling range (%d >= %d)n",
- cpl_start_subband, cpl_end_subband);
- @@ -945,8 +1036,11 @@ static int decode_audio_block(AC3DecodeContext *s, int blk)
- if (channel_mode == AC3_CHMODE_STEREO) {
- if ((s->eac3 && !blk) || get_bits1(gbc)) {
- s->num_rematrixing_bands = 4;
- - if(cpl_in_use && s->start_freq[CPL_CH] <= 61)
- + if (cpl_in_use && s->start_freq[CPL_CH] <= 61) {
- s->num_rematrixing_bands -= 1 + (s->start_freq[CPL_CH] == 37);
- + } else if (s->spx_in_use && s->spx_start_freq <= 61) {
- + s->num_rematrixing_bands -= 1;
- + }
- for(bnd=0; bnd<s->num_rematrixing_bands; bnd++)
- s->rematrixing_flags[bnd] = get_bits1(gbc);
- } else if (!blk) {
- @@ -971,6 +1065,8 @@ static int decode_audio_block(AC3DecodeContext *s, int blk)
- int prev = s->end_freq[ch];
- if (s->channel_in_cpl[ch])
- s->end_freq[ch] = s->start_freq[CPL_CH];
- + else if (s->channel_uses_spx[ch])
- + s->end_freq[ch] = s->spx_start_freq;
- else {
- int bandwidth_code = get_bits(gbc, 6);
- if (bandwidth_code > 60) {
- @@ -1167,8 +1263,6 @@ static int decode_audio_block(AC3DecodeContext *s, int blk)
- /* TODO: generate enhanced coupling coordinates and uncouple */
- - /* TODO: apply spectral extension */
- -
- /* recover coefficients if rematrixing is in use */
- if(s->channel_mode == AC3_CHMODE_STEREO)
- do_rematrixing(s);
- @@ -1184,6 +1278,10 @@ static int decode_audio_block(AC3DecodeContext *s, int blk)
- s->dsp.int32_to_float_fmul_scalar(s->transform_coeffs[ch], s->fixed_coeffs[ch], gain, 256);
- }
- + /* apply spectral extension to high frequency bins */
- + if (s->spx_in_use)
- + ff_eac3_apply_spectral_extension(s);
- +
- /* downmix and MDCT. order depends on whether block switching is used for
- any channel in this block. this is because coefficients for the long
- and short transforms cannot be mixed. */
- diff --git a/libavcodec/ac3dec.h b/libavcodec/ac3dec.h
- index 38c2deb..fa6057d 100644
- --- a/libavcodec/ac3dec.h
- +++ b/libavcodec/ac3dec.h
- @@ -42,6 +42,7 @@
- #define AC3_MAX_COEFS 256
- #define AC3_BLOCK_SIZE 256
- #define MAX_BLOCKS 6
- +#define SPX_MAX_BANDS 17
- typedef struct {
- AVCodecContext *avctx; ///< parent context
- @@ -88,6 +89,23 @@ typedef struct {
- int cpl_coords[AC3_MAX_CHANNELS][18]; ///< coupling coordinates (cplco)
- ///@}
- +///@defgroup spx spectral extension
- +///@{
- + int spx_in_use; ///< spectral extension in use (spxinu)
- + uint8_t channel_uses_spx[AC3_MAX_CHANNELS]; ///< channel uses spectral extension (chinspx)
- + int8_t spx_atten_code[AC3_MAX_CHANNELS]; ///< spx attenuation code (spxattencod)
- + int spx_start_subband; ///< spx beginning frequency band (spxbegf)
- + int spx_start_freq; ///< spx start frequency bin
- + int spx_end_freq; ///< spx end frequency bin
- + int spx_copy_start_freq; ///< spx starting frequency bin for copying (copystartmant)
- + int num_spx_bands; ///< number of spx bands (nspxbnds)
- + uint8_t spx_band_struct[SPX_MAX_BANDS]; ///< spectral extension band structure (spxbndstrc)
- + uint8_t spx_band_sizes[SPX_MAX_BANDS]; ///< number of bins in each band (spxbndsztab)
- + uint8_t first_spx_coords[AC3_MAX_CHANNELS]; ///< first spx coordinates states (firstspxcos)
- + float spx_noise_blend[AC3_MAX_CHANNELS][SPX_MAX_BANDS]; ///< spx noise blending factor (nblendfact)
- + float spx_signal_blend[AC3_MAX_CHANNELS][SPX_MAX_BANDS];///< spx signal blending factor (sblendfact)
- +///@}
- +
- ///@defgroup aht adaptive hybrid transform
- int channel_uses_aht[AC3_MAX_CHANNELS]; ///< channel AHT in use (chahtinu)
- int pre_mantissa[AC3_MAX_CHANNELS][AC3_MAX_COEFS][MAX_BLOCKS]; ///< pre-IDCT mantissas
- @@ -179,4 +197,11 @@ int ff_eac3_parse_header(AC3DecodeContext *s);
- */
- void ff_eac3_decode_transform_coeffs_aht_ch(AC3DecodeContext *s, int ch);
- +/**
- + * Apply spectral extension to each channel by copying lower frequency
- + * coefficients to higher frequency bins and applying side information to
- + * approximate the original high frequency signal.
- + */
- +void ff_eac3_apply_spectral_extension(AC3DecodeContext *s);
- +
- #endif /* AVCODEC_AC3DEC_H */
- diff --git a/libavcodec/ac3dec_data.c b/libavcodec/ac3dec_data.c
- index 907a3ae..abe359b 100644
- --- a/libavcodec/ac3dec_data.c
- +++ b/libavcodec/ac3dec_data.c
- @@ -64,3 +64,9 @@ const uint8_t ff_eac3_hebap_tab[64] = {
- */
- const uint8_t ff_eac3_default_cpl_band_struct[18] =
- { 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1 };
- +
- +/**
- + * Table E2.15 Default Spectral Extension Banding Structure
- + */
- +const uint8_t ff_eac3_default_spx_band_struct[17] =
- +{ 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1 };
- diff --git a/libavcodec/ac3dec_data.h b/libavcodec/ac3dec_data.h
- index 8d9db05..9ed7c73 100644
- --- a/libavcodec/ac3dec_data.h
- +++ b/libavcodec/ac3dec_data.h
- @@ -29,5 +29,6 @@ extern const uint8_t ff_ac3_rematrix_band_tab[5];
- extern const uint8_t ff_eac3_hebap_tab[64];
- extern const uint8_t ff_eac3_default_cpl_band_struct[18];
- +extern const uint8_t ff_eac3_default_spx_band_struct[17];
- #endif /* AVCODEC_AC3DEC_DATA_H */
- diff --git a/libavcodec/eac3dec.c b/libavcodec/eac3dec.c
- index 3784ccf..3a78540 100644
- --- a/libavcodec/eac3dec.c
- +++ b/libavcodec/eac3dec.c
- @@ -23,10 +23,6 @@
- /*
- * There are several features of E-AC-3 that this decoder does not yet support.
- *
- - * Spectral Extension
- - * There is a patch to get this working for the two samples we have that
- - * use it, but it needs some minor changes in order to be accepted.
- - *
- * Enhanced Coupling
- * No known samples exist. If any ever surface, this feature should not be
- * too difficult to implement.
- @@ -67,6 +63,95 @@ typedef enum {
- #define EAC3_SR_CODE_REDUCED 3
- +void ff_eac3_apply_spectral_extension(AC3DecodeContext *s)
- +{
- + int bin, bnd, ch, i;
- + uint8_t wrapflag[SPX_MAX_BANDS]={1,0,}, num_copy_sections, copy_sizes[SPX_MAX_BANDS];
- + float rms_energy[SPX_MAX_BANDS];
- +
- + /* Set copy index mapping table. Set wrap flags to apply a notch filter at
- + wrap points later on. */
- + bin = s->spx_copy_start_freq;
- + num_copy_sections = 0;
- + for (bnd = 0; bnd < s->num_spx_bands; bnd++) {
- + int copysize;
- + int bandsize = s->spx_band_sizes[bnd];
- + if (bin + bandsize > s->spx_start_freq) {
- + copy_sizes[num_copy_sections++] = bin - s->spx_copy_start_freq;
- + bin = s->spx_copy_start_freq;
- + wrapflag[bnd] = 1;
- + }
- + for (i = 0; i < bandsize; i += copysize) {
- + if (bin == s->spx_start_freq) {
- + copy_sizes[num_copy_sections++] = bin - s->spx_copy_start_freq;
- + bin = s->spx_copy_start_freq;
- + }
- + copysize = FFMIN(bandsize - i, s->spx_start_freq - bin);
- + bin += copysize;
- + }
- + }
- + copy_sizes[num_copy_sections++] = bin - s->spx_copy_start_freq;
- +
- + for (ch = 1; ch <= s->fbw_channels; ch++) {
- + if (!s->channel_uses_spx[ch])
- + continue;
- +
- + /* Copy coeffs from normal bands to extension bands */
- + bin = s->spx_start_freq;
- + for (i = 0; i < num_copy_sections; i++) {
- + memcpy(&s->transform_coeffs[ch][bin],
- + &s->transform_coeffs[ch][s->spx_copy_start_freq],
- + copy_sizes[i]*sizeof(float));
- + bin += copy_sizes[i];
- + }
- +
- + /* Calculate RMS energy for each SPX band. */
- + bin = s->spx_start_freq;
- + for (bnd = 0; bnd < s->num_spx_bands; bnd++) {
- + int bandsize = s->spx_band_sizes[bnd];
- + float accum = 0.0f;
- + for (i = 0; i < bandsize; i++) {
- + float coeff = s->transform_coeffs[ch][bin++];
- + accum += coeff * coeff;
- + }
- + rms_energy[bnd] = sqrtf(accum / bandsize);
- + }
- +
- + /* Apply a notch filter at transitions between normal and extension
- + bands and at all wrap points. */
- + if (s->spx_atten_code[ch] >= 0) {
- + const float *atten_tab = ff_eac3_spx_atten_tab[s->spx_atten_code[ch]];
- + bin = s->spx_start_freq - 2;
- + for (bnd = 0; bnd < s->num_spx_bands; bnd++) {
- + if (wrapflag[bnd]) {
- + float *coeffs = &s->transform_coeffs[ch][bin];
- + coeffs[0] *= atten_tab[0];
- + coeffs[1] *= atten_tab[1];
- + coeffs[2] *= atten_tab[2];
- + coeffs[3] *= atten_tab[1];
- + coeffs[4] *= atten_tab[0];
- + }
- + bin += s->spx_band_sizes[bnd];
- + }
- + }
- +
- + /* Apply noise-blended coefficient scaling based on previously
- + calculated RMS energy, blending factors, and SPX coordinates for
- + each band. */
- + bin = s->spx_start_freq;
- + for (bnd = 0; bnd < s->num_spx_bands; bnd++) {
- + float nscale = s->spx_noise_blend[ch][bnd] * rms_energy[bnd] * (1.0f/(1<<31));
- + float sscale = s->spx_signal_blend[ch][bnd];
- + for (i = 0; i < s->spx_band_sizes[bnd]; i++) {
- + float noise = nscale * (int32_t)av_lfg_get(&s->dith_state);
- + s->transform_coeffs[ch][bin] *= sscale;
- + s->transform_coeffs[ch][bin++] += noise;
- + }
- + }
- + }
- +}
- +
- +
- /** lrint(M_SQRT2*cos(2*M_PI/12)*(1<<23)) */
- #define COEFF_0 10273905LL
- @@ -492,13 +577,11 @@ int ff_eac3_parse_header(AC3DecodeContext *s)
- }
- /* spectral extension attenuation data */
- - if (parse_spx_atten_data) {
- - av_log_missing_feature(s->avctx, "Spectral extension attenuation", 1);
- - for (ch = 1; ch <= s->fbw_channels; ch++) {
- - if (get_bits1(gbc)) { // channel has spx attenuation
- - skip_bits(gbc, 5); // skip spx attenuation code
- - }
- - }
- + for (ch = 1; ch <= s->fbw_channels; ch++) {
- + if (parse_spx_atten_data && get_bits1(gbc))
- + s->spx_atten_code[ch] = get_bits(gbc, 5);
- + else
- + s->spx_atten_code[ch] = -1;
- }
- /* block start information */
- @@ -514,6 +597,7 @@ int ff_eac3_parse_header(AC3DecodeContext *s)
- /* syntax state initialization */
- for (ch = 1; ch <= s->fbw_channels; ch++) {
- + s->first_spx_coords[ch] = 1;
- s->first_cpl_coords[ch] = 1;
- }
- s->first_cpl_leak = 1;
- diff --git a/libavcodec/eac3dec_data.c b/libavcodec/eac3dec_data.c
- index 6c6a551..9e9f8a2 100644
- --- a/libavcodec/eac3dec_data.c
- +++ b/libavcodec/eac3dec_data.c
- @@ -1093,3 +1093,42 @@ const uint8_t ff_eac3_frm_expstr[32][6] = {
- { EXP_D45, EXP_D45, EXP_D45, EXP_D45, EXP_D25, EXP_REUSE},
- { EXP_D45, EXP_D45, EXP_D45, EXP_D45, EXP_D45, EXP_D45},
- };
- +
- +/**
- + * Table E.25: Spectral Extension Attenuation Table
- + * ff_eac3_spx_atten_tab[code][bin]=pow(2.0,(bin+1)*(code+1)/-15.0);
- + */
- +const float ff_eac3_spx_atten_tab[32][3] = {
- + { 0.954841603910416503f, 0.911722488558216804f, 0.870550563296124125f },
- + { 0.911722488558216804f, 0.831237896142787758f, 0.757858283255198995f },
- + { 0.870550563296124125f, 0.757858283255198995f, 0.659753955386447100f },
- + { 0.831237896142787758f, 0.690956439983888004f, 0.574349177498517438f },
- + { 0.793700525984099792f, 0.629960524947436595f, 0.500000000000000000f },
- + { 0.757858283255198995f, 0.574349177498517438f, 0.435275281648062062f },
- + { 0.723634618720189082f, 0.523647061410313364f, 0.378929141627599553f },
- + { 0.690956439983888004f, 0.477420801955208307f, 0.329876977693223550f },
- + { 0.659753955386447100f, 0.435275281648062062f, 0.287174588749258719f },
- + { 0.629960524947436595f, 0.396850262992049896f, 0.250000000000000000f },
- + { 0.601512518041058319f, 0.361817309360094541f, 0.217637640824031003f },
- + { 0.574349177498517438f, 0.329876977693223550f, 0.189464570813799776f },
- + { 0.548412489847312945f, 0.300756259020529160f, 0.164938488846611775f },
- + { 0.523647061410313364f, 0.274206244923656473f, 0.143587294374629387f },
- + { 0.500000000000000000f, 0.250000000000000000f, 0.125000000000000000f },
- + { 0.477420801955208307f, 0.227930622139554201f, 0.108818820412015502f },
- + { 0.455861244279108402f, 0.207809474035696939f, 0.094732285406899888f },
- + { 0.435275281648062062f, 0.189464570813799776f, 0.082469244423305887f },
- + { 0.415618948071393879f, 0.172739109995972029f, 0.071793647187314694f },
- + { 0.396850262992049896f, 0.157490131236859149f, 0.062500000000000000f },
- + { 0.378929141627599553f, 0.143587294374629387f, 0.054409410206007751f },
- + { 0.361817309360094541f, 0.130911765352578369f, 0.047366142703449930f },
- + { 0.345478219991944002f, 0.119355200488802049f, 0.041234622211652958f },
- + { 0.329876977693223550f, 0.108818820412015502f, 0.035896823593657347f },
- + { 0.314980262473718298f, 0.099212565748012460f, 0.031250000000000000f },
- + { 0.300756259020529160f, 0.090454327340023621f, 0.027204705103003875f },
- + { 0.287174588749258719f, 0.082469244423305887f, 0.023683071351724965f },
- + { 0.274206244923656473f, 0.075189064755132290f, 0.020617311105826479f },
- + { 0.261823530705156682f, 0.068551561230914118f, 0.017948411796828673f },
- + { 0.250000000000000000f, 0.062500000000000000f, 0.015625000000000000f },
- + { 0.238710400977604098f, 0.056982655534888536f, 0.013602352551501938f },
- + { 0.227930622139554201f, 0.051952368508924235f, 0.011841535675862483f }
- +};
- diff --git a/libavcodec/eac3dec_data.h b/libavcodec/eac3dec_data.h
- index 76dd154..1331833 100644
- --- a/libavcodec/eac3dec_data.h
- +++ b/libavcodec/eac3dec_data.h
- @@ -31,5 +31,6 @@ extern const int16_t ff_eac3_gaq_remap_2_4_b[9][2];
- extern const int16_t (* const ff_eac3_mantissa_vq[8])[6];
- extern const uint8_t ff_eac3_frm_expstr[32][6];
- +extern const float ff_eac3_spx_atten_tab[32][3];
- #endif /* AVCODEC_EAC3DEC_DATA_H */