Merge commit '208f3abb917757743313da0da714e525e03159d2'
authorMichael Niedermayer <michaelni@gmx.at>
Mon, 24 Nov 2014 12:46:29 +0000 (13:46 +0100)
committerMichael Niedermayer <michaelni@gmx.at>
Mon, 24 Nov 2014 12:48:31 +0000 (13:48 +0100)
* commit '208f3abb917757743313da0da714e525e03159d2':
  aacsbr: always initialize max_qmf_subbands

See: c6d3b3be1555257ff3f88da6b8dca2158dad2a85
Merged-by: Michael Niedermayer <michaelni@gmx.at>
1  2 
libavcodec/aacsbr.c

diff --combined libavcodec/aacsbr.c
@@@ -3,20 -3,20 +3,20 @@@
   * Copyright (c) 2008-2009 Robert Swain ( rob opendot cl )
   * Copyright (c) 2009-2010 Alex Converse <alex.converse@gmail.com>
   *
 - * This file is part of Libav.
 + * This file is part of FFmpeg.
   *
 - * Libav is free software; you can redistribute it and/or
 + * FFmpeg is free software; you can redistribute it and/or
   * modify it under the terms of the GNU Lesser General Public
   * License as published by the Free Software Foundation; either
   * version 2.1 of the License, or (at your option) any later version.
   *
 - * Libav is distributed in the hope that it will be useful,
 + * FFmpeg is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   * Lesser General Public License for more details.
   *
   * You should have received a copy of the GNU Lesser General Public
 - * License along with Libav; if not, write to the Free Software
 + * License along with FFmpeg; if not, write to the Free Software
   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
   */
  
  #include "sbr.h"
  #include "aacsbr.h"
  #include "aacsbrdata.h"
 +#include "aacsbr_tablegen.h"
  #include "fft.h"
  #include "aacps.h"
  #include "sbrdsp.h"
  #include "libavutil/internal.h"
  #include "libavutil/libm.h"
 +#include "libavutil/avassert.h"
  
  #include <stdint.h>
  #include <float.h>
 +#include <math.h>
  
  #define ENVELOPE_ADJUSTMENT_OFFSET 2
  #define NOISE_FLOOR_OFFSET 6.0f
  
 +#if ARCH_MIPS
 +#include "mips/aacsbr_mips.h"
 +#endif /* ARCH_MIPS */
 +
  /**
   * SBR VLC tables
   */
@@@ -92,10 -85,9 +92,10 @@@ static const int8_t vlc_sbr_lav[10] 
  #define SBR_VLC_ROW(name) \
      { name ## _codes, name ## _bits, sizeof(name ## _codes), sizeof(name ## _codes[0]) }
  
 +static void aacsbr_func_ptr_init(AACSBRContext *c);
 +
  av_cold void ff_aac_sbr_init(void)
  {
 -    int n;
      static const struct {
          const void *sbr_codes, *sbr_bits;
          const unsigned int table_size, elem_size;
      SBR_INIT_VLC_STATIC(8, 592);
      SBR_INIT_VLC_STATIC(9, 512);
  
 -    for (n = 1; n < 320; n++)
 -        sbr_qmf_window_us[320 + n] = sbr_qmf_window_us[320 - n];
 -    sbr_qmf_window_us[384] = -sbr_qmf_window_us[384];
 -    sbr_qmf_window_us[512] = -sbr_qmf_window_us[512];
 -
 -    for (n = 0; n < 320; n++)
 -        sbr_qmf_window_ds[n] = sbr_qmf_window_us[2*n];
 +    aacsbr_tableinit();
  
      ff_ps_init();
  }
@@@ -142,8 -140,6 +142,8 @@@ static void sbr_turnoff(SpectralBandRep
  
  av_cold void ff_aac_sbr_ctx_init(AACContext *ac, SpectralBandReplication *sbr)
  {
 +    if(sbr->mdct.mdct_bits)
 +        return;
      sbr->kx[0] = sbr->kx[1];
      sbr_turnoff(sbr);
      sbr->data[0].synthesis_filterbank_samples_offset = SBR_SYNTHESIS_BUF_SIZE - (1280 - 128);
      ff_mdct_init(&sbr->mdct_ana, 7, 1, -2.0 * 32768.0);
      ff_ps_ctx_init(&sbr->ps);
      ff_sbrdsp_init(&sbr->dsp);
 +    aacsbr_func_ptr_init(&sbr->c);
  }
  
  av_cold void ff_aac_sbr_ctx_close(SpectralBandReplication *sbr)
@@@ -326,7 -321,7 +326,7 @@@ static int check_n_master(AVCodecContex
  static int sbr_make_f_master(AACContext *ac, SpectralBandReplication *sbr,
                               SpectrumParameters *spectrum)
  {
-     unsigned int temp, max_qmf_subbands;
+     unsigned int temp, max_qmf_subbands = 0;
      unsigned int start_min, stop_min;
      int k;
      const int8_t *sbr_offset_ptr;
      } else
          temp = 5000;
  
 -    start_min = ((temp << 7) + (sbr->sample_rate >> 1)) / sbr->sample_rate;
 -    stop_min  = ((temp << 8) + (sbr->sample_rate >> 1)) / sbr->sample_rate;
 -
      switch (sbr->sample_rate) {
      case 16000:
          sbr_offset_ptr = sbr_offset[0];
          return -1;
      }
  
 +    start_min = ((temp << 7) + (sbr->sample_rate >> 1)) / sbr->sample_rate;
 +    stop_min  = ((temp << 8) + (sbr->sample_rate >> 1)) / sbr->sample_rate;
 +
      sbr->k[0] = start_min + sbr_offset_ptr[spectrum->bs_start_freq];
  
      if (spectrum->bs_stop_freq < 14) {
          max_qmf_subbands = 35;
      } else if (sbr->sample_rate >= 48000)
          max_qmf_subbands = 32;
 +    else
 +        av_assert0(0);
  
      if (sbr->k[2] - sbr->k[0] > max_qmf_subbands) {
          av_log(ac->avctx, AV_LOG_ERROR,
@@@ -751,7 -744,7 +751,7 @@@ static int read_sbr_grid(AACContext *ac
          if (ch_data->bs_frame_class == FIXFIX) {
              idx = ch_data->bs_num_env >> 1;
          } else if (ch_data->bs_frame_class & 1) { // FIXVAR or VARVAR
 -            idx = ch_data->bs_num_env - FFMAX(bs_pointer - 1, 1);
 +            idx = ch_data->bs_num_env - FFMAX((int)bs_pointer - 1, 1);
          } else { // VARFIX
              if (!bs_pointer)
                  idx = 1;
@@@ -936,9 -929,7 +936,9 @@@ static void read_sbr_extension(AACConte
          }
          break;
      default:
 -        avpriv_request_sample(ac->avctx, "Reserved SBR extensions");
 +        // some files contain 0-padding
 +        if (bs_extension_id || *num_bits_left > 16 || show_bits(gb, *num_bits_left))
 +            avpriv_request_sample(ac->avctx, "Reserved SBR extensions");
          skip_bits_long(gb, *num_bits_left); // bs_fill_bits
          *num_bits_left = 0;
          break;
@@@ -1127,12 -1118,7 +1127,12 @@@ static void sbr_dequant(SpectralBandRep
              for (k = 0; k < sbr->n[sbr->data[0].bs_freq_res[e]]; k++) {
                  float temp1 = exp2f(sbr->data[0].env_facs[e][k] * alpha + 7.0f);
                  float temp2 = exp2f((pan_offset - sbr->data[1].env_facs[e][k]) * alpha);
 -                float fac   = temp1 / (1.0f + temp2);
 +                float fac;
 +                if (temp1 > 1E20) {
 +                    av_log(NULL, AV_LOG_ERROR, "envelope scalefactor overflow in dequant\n");
 +                    temp1 = 1;
 +                }
 +                fac   = temp1 / (1.0f + temp2);
                  sbr->data[0].env_facs[e][k] = fac;
                  sbr->data[1].env_facs[e][k] = fac * temp2;
              }
              for (k = 0; k < sbr->n_q; k++) {
                  float temp1 = exp2f(NOISE_FLOOR_OFFSET - sbr->data[0].noise_facs[e][k] + 1);
                  float temp2 = exp2f(12 - sbr->data[1].noise_facs[e][k]);
 -                float fac   = temp1 / (1.0f + temp2);
 +                float fac;
 +                if (temp1 > 1E20) {
 +                    av_log(NULL, AV_LOG_ERROR, "envelope scalefactor overflow in dequant\n");
 +                    temp1 = 1;
 +                }
 +                fac = temp1 / (1.0f + temp2);
                  sbr->data[0].noise_facs[e][k] = fac;
                  sbr->data[1].noise_facs[e][k] = fac * temp2;
              }
          for (ch = 0; ch < (id_aac == TYPE_CPE) + 1; ch++) {
              float alpha = sbr->data[ch].bs_amp_res ? 1.0f : 0.5f;
              for (e = 1; e <= sbr->data[ch].bs_num_env; e++)
 -                for (k = 0; k < sbr->n[sbr->data[ch].bs_freq_res[e]]; k++)
 +                for (k = 0; k < sbr->n[sbr->data[ch].bs_freq_res[e]]; k++){
                      sbr->data[ch].env_facs[e][k] =
                          exp2f(alpha * sbr->data[ch].env_facs[e][k] + 6.0f);
 +                    if (sbr->data[ch].env_facs[e][k] > 1E20) {
 +                        av_log(NULL, AV_LOG_ERROR, "envelope scalefactor overflow in dequant\n");
 +                        sbr->data[ch].env_facs[e][k] = 1;
 +                    }
 +                }
 +
              for (e = 1; e <= sbr->data[ch].bs_num_noise; e++)
                  for (k = 0; k < sbr->n_q; k++)
                      sbr->data[ch].noise_facs[e][k] =
   * @param   x       pointer to the beginning of the first sample window
   * @param   W       array of complex-valued samples split into subbands
   */
 +#ifndef sbr_qmf_analysis
  static void sbr_qmf_analysis(AVFloatDSPContext *dsp, FFTContext *mdct,
                               SBRDSPContext *sbrdsp, const float *in, float *x,
                               float z[320], float W[2][32][32][2], int buf_idx)
          x += 32;
      }
  }
 +#endif
  
  /**
   * Synthesis QMF Bank (14496-3 sp04 p206) and Downsampled Synthesis QMF Bank
   * (14496-3 sp04 p206)
   */
 +#ifndef sbr_qmf_synthesis
  static void sbr_qmf_synthesis(FFTContext *mdct,
                                SBRDSPContext *sbrdsp, AVFloatDSPContext *dsp,
                                float *out, float X[2][38][64],
          out += 64 >> div;
      }
  }
 +#endif
  
  /** High Frequency Generation (14496-3 sp04 p214+) and Inverse Filtering
   * (14496-3 sp04 p214)
@@@ -1602,6 -1573,10 +1602,6 @@@ static void sbr_hf_assemble(float Y1[38
          0.11516383427084,
          0.03183050093751,
      };
 -    static const int8_t phi[2][4] = {
 -        {  1,  0, -1,  0}, // real
 -        {  0,  1,  0, -1}, // imaginary
 -    };
      float (*g_temp)[48] = ch_data->g_temp, (*q_temp)[48] = ch_data->q_temp;
      int indexnoise = ch_data->f_indexnoise;
      int indexsine  = ch_data->f_indexsine;
  
      for (e = 0; e < ch_data->bs_num_env; e++) {
          for (i = 2 * ch_data->t_env[e]; i < 2 * ch_data->t_env[e + 1]; i++) {
 -            int phi_sign = (1 - 2*(kx & 1));
              LOCAL_ALIGNED_16(float, g_filt_tab, [48]);
              LOCAL_ALIGNED_16(float, q_filt_tab, [48]);
              float *g_filt, *q_filt;
                                                     q_filt, indexnoise,
                                                     kx, m_max);
              } else {
 -                for (m = 0; m < m_max; m++) {
 -                    Y1[i][m + kx][0] +=
 -                        sbr->s_m[e][m] * phi[0][indexsine];
 -                    Y1[i][m + kx][1] +=
 -                        sbr->s_m[e][m] * (phi[1][indexsine] * phi_sign);
 -                    phi_sign = -phi_sign;
 +                int idx = indexsine&1;
 +                int A = (1-((indexsine+(kx & 1))&2));
 +                int B = (A^(-idx)) + idx;
 +                float *out = &Y1[i][kx][idx];
 +                float *in  = sbr->s_m[e];
 +                for (m = 0; m+1 < m_max; m+=2) {
 +                    out[2*m  ] += in[m  ] * A;
 +                    out[2*m+2] += in[m+1] * B;
                  }
 +                if(m_max&1)
 +                    out[2*m  ] += in[m  ] * A;
              }
              indexnoise = (indexnoise + m_max) & 0x1ff;
              indexsine = (indexsine + 1) & 3;
@@@ -1703,13 -1675,13 +1703,13 @@@ void ff_sbr_apply(AACContext *ac, Spect
          sbr_qmf_analysis(&ac->fdsp, &sbr->mdct_ana, &sbr->dsp, ch ? R : L, sbr->data[ch].analysis_filterbank_samples,
                           (float*)sbr->qmf_filter_scratch,
                           sbr->data[ch].W, sbr->data[ch].Ypos);
 -        sbr_lf_gen(ac, sbr, sbr->X_low,
 -                   (const float (*)[32][32][2]) sbr->data[ch].W,
 -                   sbr->data[ch].Ypos);
 +        sbr->c.sbr_lf_gen(ac, sbr, sbr->X_low,
 +                          (const float (*)[32][32][2]) sbr->data[ch].W,
 +                          sbr->data[ch].Ypos);
          sbr->data[ch].Ypos ^= 1;
          if (sbr->start) {
 -            sbr_hf_inverse_filter(&sbr->dsp, sbr->alpha0, sbr->alpha1,
 -                                  (const float (*)[40][2]) sbr->X_low, sbr->k[0]);
 +            sbr->c.sbr_hf_inverse_filter(&sbr->dsp, sbr->alpha0, sbr->alpha1,
 +                                         (const float (*)[40][2]) sbr->X_low, sbr->k[0]);
              sbr_chirp(sbr, &sbr->data[ch]);
              sbr_hf_gen(ac, sbr, sbr->X_high,
                         (const float (*)[40][2]) sbr->X_low,
              if (!err) {
                  sbr_env_estimate(sbr->e_curr, sbr->X_high, sbr, &sbr->data[ch]);
                  sbr_gain_calc(ac, sbr, &sbr->data[ch], sbr->data[ch].e_a);
 -                sbr_hf_assemble(sbr->data[ch].Y[sbr->data[ch].Ypos],
 +                sbr->c.sbr_hf_assemble(sbr->data[ch].Y[sbr->data[ch].Ypos],
                                  (const float (*)[40][2]) sbr->X_high,
                                  sbr, &sbr->data[ch],
                                  sbr->data[ch].e_a);
          }
  
          /* synthesis */
 -        sbr_x_gen(sbr, sbr->X[ch],
 +        sbr->c.sbr_x_gen(sbr, sbr->X[ch],
                    (const float (*)[64][2]) sbr->data[ch].Y[1-sbr->data[ch].Ypos],
                    (const float (*)[64][2]) sbr->data[ch].Y[  sbr->data[ch].Ypos],
                    (const float (*)[40][2]) sbr->X_low, ch);
                            &sbr->data[1].synthesis_filterbank_samples_offset,
                            downsampled);
  }
 +
 +static void aacsbr_func_ptr_init(AACSBRContext *c)
 +{
 +    c->sbr_lf_gen            = sbr_lf_gen;
 +    c->sbr_hf_assemble       = sbr_hf_assemble;
 +    c->sbr_x_gen             = sbr_x_gen;
 +    c->sbr_hf_inverse_filter = sbr_hf_inverse_filter;
 +
 +    if(ARCH_MIPS)
 +        ff_aacsbr_func_ptr_init_mips(c);
 +}