]> git.sesse.net Git - ffmpeg/commitdiff
Merge commit 'd316f9cefcd854071985c6f524a9a15348240264'
authorJames Almer <jamrial@gmail.com>
Fri, 31 Mar 2017 19:33:48 +0000 (16:33 -0300)
committerJames Almer <jamrial@gmail.com>
Fri, 31 Mar 2017 19:33:48 +0000 (16:33 -0300)
* commit 'd316f9cefcd854071985c6f524a9a15348240264':
  aac: Drop pointless cast

Merged-by: James Almer <jamrial@gmail.com>
1  2 
libavcodec/aacpsy.c

diff --combined libavcodec/aacpsy.c
index e32faaa908075a748932321861991ff7af8a224a,272be9f1371cddca59a5df6108fd4dac1e54b234..fca692cb153f17082e3bcb918841b8e2bbbfe2c4
@@@ -2,20 -2,20 +2,20 @@@
   * AAC encoder psychoacoustic model
   * Copyright (C) 2008 Konstantin Shishkov
   *
 - * 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
   */
  
@@@ -25,8 -25,6 +25,8 @@@
   */
  
  #include "libavutil/attributes.h"
 +#include "libavutil/ffmath.h"
 +
  #include "avcodec.h"
  #include "aactab.h"
  #include "psymodel.h"
@@@ -80,8 -78,6 +80,8 @@@
  #define PSY_3GPP_AH_THR_LONG    0.5f
  #define PSY_3GPP_AH_THR_SHORT   0.63f
  
 +#define PSY_PE_FORGET_SLOPE  511
 +
  enum {
      PSY_3GPP_AH_NONE,
      PSY_3GPP_AH_INACTIVE,
@@@ -89,7 -85,6 +89,7 @@@
  };
  
  #define PSY_3GPP_BITS_TO_PE(bits) ((bits) * 1.18f)
 +#define PSY_3GPP_PE_TO_BITS(bits) ((bits) / 1.18f)
  
  /* LAME psy model constants */
  #define PSY_LAME_FIR_LEN 21         ///< LAME psy model FIR order
@@@ -160,7 -155,6 +160,7 @@@ typedef struct AacPsyContext
      } pe;
      AacPsyCoeffs psy_coef[2][64];
      AacPsyChannel *ch;
 +    float global_quality; ///< normalized global quality taken from avctx
  }AacPsyContext;
  
  /**
@@@ -222,10 -216,6 +222,10 @@@ static const float psy_fir_coeffs[] = 
      -5.52212e-17 * 2, -0.313819 * 2
  };
  
 +#if ARCH_MIPS
 +#   include "mips/aacpsy_mips.h"
 +#endif /* ARCH_MIPS */
 +
  /**
   * Calculate the ABR attack threshold from the above LAME psymodel table.
   */
@@@ -303,24 -293,17 +303,24 @@@ static av_cold int psy_3gpp_init(FFPsyC
      float bark;
      int i, j, g, start;
      float prev, minscale, minath, minsnr, pe_min;
 -    const int chan_bitrate = ctx->avctx->bit_rate / ctx->avctx->channels;
 -    const int bandwidth    = ctx->avctx->cutoff ? ctx->avctx->cutoff : ctx->avctx->sample_rate / 2;
 +    int chan_bitrate = ctx->avctx->bit_rate / ((ctx->avctx->flags & AV_CODEC_FLAG_QSCALE) ? 2.0f : ctx->avctx->channels);
 +
 +    const int bandwidth    = ctx->cutoff ? ctx->cutoff : AAC_CUTOFF(ctx->avctx);
      const float num_bark   = calc_bark((float)bandwidth);
  
      ctx->model_priv_data = av_mallocz(sizeof(AacPsyContext));
      if (!ctx->model_priv_data)
          return AVERROR(ENOMEM);
-     pctx = (AacPsyContext*) ctx->model_priv_data;
+     pctx = ctx->model_priv_data;
 +    pctx->global_quality = (ctx->avctx->global_quality ? ctx->avctx->global_quality : 120) * 0.01f;
 +
 +    if (ctx->avctx->flags & AV_CODEC_FLAG_QSCALE) {
 +        /* Use the target average bitrate to compute spread parameters */
 +        chan_bitrate = (int)(chan_bitrate / 120.0 * (ctx->avctx->global_quality ? ctx->avctx->global_quality : 120));
 +    }
  
      pctx->chan_bitrate = chan_bitrate;
 -    pctx->frame_bits   = chan_bitrate * AAC_BLOCK_SIZE_LONG / ctx->avctx->sample_rate;
 +    pctx->frame_bits   = FFMIN(2560, chan_bitrate * AAC_BLOCK_SIZE_LONG / ctx->avctx->sample_rate);
      pctx->pe.min       =  8.0f * AAC_BLOCK_SIZE_LONG * bandwidth / (ctx->avctx->sample_rate * 2.0f);
      pctx->pe.max       = 12.0f * AAC_BLOCK_SIZE_LONG * bandwidth / (ctx->avctx->sample_rate * 2.0f);
      ctx->bitres.size   = 6144 - pctx->frame_bits;
          for (g = 0; g < ctx->num_bands[j] - 1; g++) {
              AacPsyCoeffs *coeff = &coeffs[g];
              float bark_width = coeffs[g+1].barks - coeffs->barks;
 -            coeff->spread_low[0] = pow(10.0, -bark_width * PSY_3GPP_THR_SPREAD_LOW);
 -            coeff->spread_hi [0] = pow(10.0, -bark_width * PSY_3GPP_THR_SPREAD_HI);
 -            coeff->spread_low[1] = pow(10.0, -bark_width * en_spread_low);
 -            coeff->spread_hi [1] = pow(10.0, -bark_width * en_spread_hi);
 +            coeff->spread_low[0] = ff_exp10(-bark_width * PSY_3GPP_THR_SPREAD_LOW);
 +            coeff->spread_hi [0] = ff_exp10(-bark_width * PSY_3GPP_THR_SPREAD_HI);
 +            coeff->spread_low[1] = ff_exp10(-bark_width * en_spread_low);
 +            coeff->spread_hi [1] = ff_exp10(-bark_width * en_spread_hi);
              pe_min = bark_pe * bark_width;
 -            minsnr = pow(2.0f, pe_min / band_sizes[g]) - 1.5f;
 +            minsnr = exp2(pe_min / band_sizes[g]) - 1.5f;
              coeff->min_snr = av_clipf(1.0f / minsnr, PSY_SNR_25DB, PSY_SNR_1DB);
          }
          start = 0;
          }
      }
  
 -    pctx->ch = av_mallocz(sizeof(AacPsyChannel) * ctx->avctx->channels);
 +    pctx->ch = av_mallocz_array(ctx->avctx->channels, sizeof(AacPsyChannel));
      if (!pctx->ch) {
 -        av_freep(&pctx);
 +        av_freep(&ctx->model_priv_data);
          return AVERROR(ENOMEM);
      }
  
@@@ -408,7 -391,7 +408,7 @@@ static av_unused FFPsyWindowInfo psy_3g
                                                   int channel, int prev_type)
  {
      int i, j;
 -    int br               = ctx->avctx->bit_rate / ctx->avctx->channels;
 +    int br               = ((AacPsyContext*)ctx->model_priv_data)->chan_bitrate;
      int attack_ratio     = br <= 16000 ? 18 : 10;
      AacPsyContext *pctx = (AacPsyContext*) ctx->model_priv_data;
      AacPsyChannel *pch  = &pctx->ch[channel];
@@@ -497,7 -480,7 +497,7 @@@ static int calc_bit_demand(AacPsyContex
      const float bitspend_add   = short_window ? PSY_3GPP_SPEND_ADD_S   : PSY_3GPP_SPEND_ADD_L;
      const float clip_low       = short_window ? PSY_3GPP_CLIP_LO_S     : PSY_3GPP_CLIP_LO_L;
      const float clip_high      = short_window ? PSY_3GPP_CLIP_HI_S     : PSY_3GPP_CLIP_HI_L;
 -    float clipped_pe, bit_save, bit_spend, bit_factor, fill_level;
 +    float clipped_pe, bit_save, bit_spend, bit_factor, fill_level, forgetful_min_pe;
  
      ctx->fill_level += ctx->frame_bits - bits;
      ctx->fill_level  = av_clip(ctx->fill_level, 0, size);
       * Hopefully below is correct.
       */
      bit_factor = 1.0f - bit_save + ((bit_spend - bit_save) / (ctx->pe.max - ctx->pe.min)) * (clipped_pe - ctx->pe.min);
 -    /* NOTE: The reference encoder attempts to center pe max/min around the current pe. */
 +    /* NOTE: The reference encoder attempts to center pe max/min around the current pe.
 +     * Here we do that by slowly forgetting pe.min when pe stays in a range that makes
 +     * it unlikely (ie: above the mean)
 +     */
      ctx->pe.max = FFMAX(pe, ctx->pe.max);
 -    ctx->pe.min = FFMIN(pe, ctx->pe.min);
 +    forgetful_min_pe = ((ctx->pe.min * PSY_PE_FORGET_SLOPE)
 +        + FFMAX(ctx->pe.min, pe * (pe / ctx->pe.max))) / (PSY_PE_FORGET_SLOPE + 1);
 +    ctx->pe.min = FFMIN(pe, forgetful_min_pe);
  
 -    return FFMIN(ctx->frame_bits * bit_factor, ctx->frame_bits + size - bits);
 +    /* NOTE: allocate a minimum of 1/8th average frame bits, to avoid
 +     *   reservoir starvation from producing zero-bit frames
 +     */
 +    return FFMIN(
 +        ctx->frame_bits * bit_factor,
 +        FFMAX(ctx->frame_bits + size - bits, ctx->frame_bits / 8));
  }
  
  static float calc_pe_3gpp(AacPsyBand *band)
@@@ -559,11 -532,8 +559,11 @@@ static float calc_reduction_3gpp(float 
  {
      float thr_avg, reduction;
  
 -    thr_avg   = powf(2.0f, (a - pe) / (4.0f * active_lines));
 -    reduction = powf(2.0f, (a - desired_pe) / (4.0f * active_lines)) - thr_avg;
 +    if(active_lines == 0.0)
 +        return 0;
 +
 +    thr_avg   = exp2f((a - pe) / (4.0f * active_lines));
 +    reduction = exp2f((a - desired_pe) / (4.0f * active_lines)) - thr_avg;
  
      return FFMAX(reduction, 0.0f);
  }
@@@ -574,10 -544,8 +574,10 @@@ static float calc_reduced_thr_3gpp(AacP
      float thr = band->thr;
  
      if (band->energy > thr) {
 -        thr = powf(thr, 0.25f) + reduction;
 -        thr = powf(thr, 4.0f);
 +        thr = sqrtf(thr);
 +        thr = sqrtf(thr) + reduction;
 +        thr *= thr;
 +        thr *= thr;
  
          /* This deviates from the 3GPP spec to match the reference encoder.
           * It performs min(thr_reduced, max(thr, energy/min_snr)) only for bands
      return thr;
  }
  
 +#ifndef calc_thr_3gpp
 +static void calc_thr_3gpp(const FFPsyWindowInfo *wi, const int num_bands, AacPsyChannel *pch,
 +                          const uint8_t *band_sizes, const float *coefs, const int cutoff)
 +{
 +    int i, w, g;
 +    int start = 0, wstart = 0;
 +    for (w = 0; w < wi->num_windows*16; w += 16) {
 +        wstart = 0;
 +        for (g = 0; g < num_bands; g++) {
 +            AacPsyBand *band = &pch->band[w+g];
 +
 +            float form_factor = 0.0f;
 +            float Temp;
 +            band->energy = 0.0f;
 +            if (wstart < cutoff) {
 +                for (i = 0; i < band_sizes[g]; i++) {
 +                    band->energy += coefs[start+i] * coefs[start+i];
 +                    form_factor  += sqrtf(fabs(coefs[start+i]));
 +                }
 +            }
 +            Temp = band->energy > 0 ? sqrtf((float)band_sizes[g] / band->energy) : 0;
 +            band->thr      = band->energy * 0.001258925f;
 +            band->nz_lines = form_factor * sqrtf(Temp);
 +
 +            start += band_sizes[g];
 +            wstart += band_sizes[g];
 +        }
 +    }
 +}
 +#endif /* calc_thr_3gpp */
 +
 +#ifndef psy_hp_filter
 +static void psy_hp_filter(const float *firbuf, float *hpfsmpl, const float *psy_fir_coeffs)
 +{
 +    int i, j;
 +    for (i = 0; i < AAC_BLOCK_SIZE_LONG; i++) {
 +        float sum1, sum2;
 +        sum1 = firbuf[i + (PSY_LAME_FIR_LEN - 1) / 2];
 +        sum2 = 0.0;
 +        for (j = 0; j < ((PSY_LAME_FIR_LEN - 1) / 2) - 1; j += 2) {
 +            sum1 += psy_fir_coeffs[j] * (firbuf[i + j] + firbuf[i + PSY_LAME_FIR_LEN - j]);
 +            sum2 += psy_fir_coeffs[j + 1] * (firbuf[i + j + 1] + firbuf[i + PSY_LAME_FIR_LEN - j - 1]);
 +        }
 +        /* NOTE: The LAME psymodel expects it's input in the range -32768 to 32768.
 +         *       Tuning this for normalized floats would be difficult. */
 +        hpfsmpl[i] = (sum1 + sum2) * 32768.0f;
 +    }
 +}
 +#endif /* psy_hp_filter */
 +
  /**
   * Calculate band thresholds as suggested in 3GPP TS26.403
   */
@@@ -651,20 -569,33 +651,20 @@@ static void psy_3gpp_analyze_channel(FF
  {
      AacPsyContext *pctx = (AacPsyContext*) ctx->model_priv_data;
      AacPsyChannel *pch  = &pctx->ch[channel];
 -    int start = 0;
      int i, w, g;
 -    float desired_bits, desired_pe, delta_pe, reduction, spread_en[128] = {0};
 +    float desired_bits, desired_pe, delta_pe, reduction= NAN, spread_en[128] = {0};
      float a = 0.0f, active_lines = 0.0f, norm_fac = 0.0f;
      float pe = pctx->chan_bitrate > 32000 ? 0.0f : FFMAX(50.0f, 100.0f - pctx->chan_bitrate * 100.0f / 32000.0f);
      const int      num_bands   = ctx->num_bands[wi->num_windows == 8];
      const uint8_t *band_sizes  = ctx->bands[wi->num_windows == 8];
      AacPsyCoeffs  *coeffs      = pctx->psy_coef[wi->num_windows == 8];
      const float avoid_hole_thr = wi->num_windows == 8 ? PSY_3GPP_AH_THR_SHORT : PSY_3GPP_AH_THR_LONG;
 +    const int bandwidth        = ctx->cutoff ? ctx->cutoff : AAC_CUTOFF(ctx->avctx);
 +    const int cutoff           = bandwidth * 2048 / wi->num_windows / ctx->avctx->sample_rate;
  
      //calculate energies, initial thresholds and related values - 5.4.2 "Threshold Calculation"
 -    for (w = 0; w < wi->num_windows*16; w += 16) {
 -        for (g = 0; g < num_bands; g++) {
 -            AacPsyBand *band = &pch->band[w+g];
 +    calc_thr_3gpp(wi, num_bands, pch, band_sizes, coefs, cutoff);
  
 -            float form_factor = 0.0f;
 -            band->energy = 0.0f;
 -            for (i = 0; i < band_sizes[g]; i++) {
 -                band->energy += coefs[start+i] * coefs[start+i];
 -                form_factor  += sqrtf(fabs(coefs[start+i]));
 -            }
 -            band->thr      = band->energy * 0.001258925f;
 -            band->nz_lines = form_factor / powf(band->energy / band_sizes[g], 0.25f);
 -
 -            start += band_sizes[g];
 -        }
 -    }
      //modify thresholds and energies - spread, threshold in quiet, pre-echo control
      for (w = 0; w < wi->num_windows*16; w += 16) {
          AacPsyBand *bands = &pch->band[w];
  
              band->thr_quiet = band->thr = FFMAX(band->thr, coeffs[g].ath);
              //5.4.2.5 "Pre-echo control"
 -            if (!(wi->window_type[0] == LONG_STOP_SEQUENCE || (wi->window_type[1] == LONG_START_SEQUENCE && !w)))
 +            if (!(wi->window_type[0] == LONG_STOP_SEQUENCE || (!w && wi->window_type[1] == LONG_START_SEQUENCE)))
                  band->thr = FFMAX(PSY_3GPP_RPEMIN*band->thr, FFMIN(band->thr,
                                    PSY_3GPP_RPELEV*pch->prev_band[w+g].thr_quiet));
  
  
      /* 5.6.1.3.2 "Calculation of the desired perceptual entropy" */
      ctx->ch[channel].entropy = pe;
 -    desired_bits = calc_bit_demand(pctx, pe, ctx->bitres.bits, ctx->bitres.size, wi->num_windows == 8);
 -    desired_pe = PSY_3GPP_BITS_TO_PE(desired_bits);
 -    /* NOTE: PE correction is kept simple. During initial testing it had very
 -     *       little effect on the final bitrate. Probably a good idea to come
 -     *       back and do more testing later.
 -     */
 -    if (ctx->bitres.bits > 0)
 -        desired_pe *= av_clipf(pctx->pe.previous / PSY_3GPP_BITS_TO_PE(ctx->bitres.bits),
 -                               0.85f, 1.15f);
 +    if (ctx->avctx->flags & AV_CODEC_FLAG_QSCALE) {
 +        /* (2.5 * 120) achieves almost transparent rate, and we want to give
 +         * ample room downwards, so we make that equivalent to QSCALE=2.4
 +         */
 +        desired_pe = pe * (ctx->avctx->global_quality ? ctx->avctx->global_quality : 120) / (2 * 2.5f * 120.0f);
 +        desired_bits = FFMIN(2560, PSY_3GPP_PE_TO_BITS(desired_pe));
 +        desired_pe = PSY_3GPP_BITS_TO_PE(desired_bits); // reflect clipping
 +
 +        /* PE slope smoothing */
 +        if (ctx->bitres.bits > 0) {
 +            desired_bits = FFMIN(2560, PSY_3GPP_PE_TO_BITS(desired_pe));
 +            desired_pe = PSY_3GPP_BITS_TO_PE(desired_bits); // reflect clipping
 +        }
 +
 +        pctx->pe.max = FFMAX(pe, pctx->pe.max);
 +        pctx->pe.min = FFMIN(pe, pctx->pe.min);
 +    } else {
 +        desired_bits = calc_bit_demand(pctx, pe, ctx->bitres.bits, ctx->bitres.size, wi->num_windows == 8);
 +        desired_pe = PSY_3GPP_BITS_TO_PE(desired_bits);
 +
 +        /* NOTE: PE correction is kept simple. During initial testing it had very
 +         *       little effect on the final bitrate. Probably a good idea to come
 +         *       back and do more testing later.
 +         */
 +        if (ctx->bitres.bits > 0)
 +            desired_pe *= av_clipf(pctx->pe.previous / PSY_3GPP_BITS_TO_PE(ctx->bitres.bits),
 +                                   0.85f, 1.15f);
 +    }
      pctx->pe.previous = PSY_3GPP_BITS_TO_PE(desired_bits);
 +    ctx->bitres.alloc = desired_bits;
  
      if (desired_pe < pe) {
          /* 5.6.1.3.4 "First Estimation of the reduction value" */
              }
              desired_pe_no_ah = FFMAX(desired_pe - (pe - pe_no_ah), 0.0f);
              if (active_lines > 0.0f)
 -                reduction += calc_reduction_3gpp(a, desired_pe_no_ah, pe_no_ah, active_lines);
 +                reduction = calc_reduction_3gpp(a, desired_pe_no_ah, pe_no_ah, active_lines);
  
              pe = 0.0f;
              for (w = 0; w < wi->num_windows*16; w += 16) {
                      if (active_lines > 0.0f)
                          band->thr = calc_reduced_thr_3gpp(band, coeffs[g].min_snr, reduction);
                      pe += calc_pe_3gpp(band);
 -                    band->norm_fac = band->active_lines / band->thr;
 +                    if (band->thr > 0.0f)
 +                        band->norm_fac = band->active_lines / band->thr;
 +                    else
 +                        band->norm_fac = 0.0f;
                      norm_fac += band->norm_fac;
                  }
              }
                          float delta_sfb_pe = band->norm_fac * norm_fac * delta_pe;
                          float thr = band->thr;
  
 -                        thr *= powf(2.0f, delta_sfb_pe / band->active_lines);
 +                        thr *= exp2f(delta_sfb_pe / band->active_lines);
                          if (thr > coeffs[g].min_snr * band->energy && band->avoid_holes == PSY_3GPP_AH_INACTIVE)
                              thr = FFMAX(band->thr, coeffs[g].min_snr * band->energy);
                          band->thr = thr;
  
              psy_band->threshold = band->thr;
              psy_band->energy    = band->energy;
 +            psy_band->spread    = band->active_lines * 2.0f / band_sizes[g];
 +            psy_band->bits      = PSY_3GPP_PE_TO_BITS(band->pe);
          }
      }
  
@@@ -895,10 -801,21 +895,10 @@@ static FFPsyWindowInfo psy_lame_window(
          float energy_subshort[(AAC_NUM_BLOCKS_SHORT + 1) * PSY_LAME_NUM_SUBBLOCKS];
          float energy_short[AAC_NUM_BLOCKS_SHORT + 1] = { 0 };
          const float *firbuf = la + (AAC_BLOCK_SIZE_SHORT/4 - PSY_LAME_FIR_LEN);
 -        int j, att_sum = 0;
 +        int att_sum = 0;
  
          /* LAME comment: apply high pass filter of fs/4 */
 -        for (i = 0; i < AAC_BLOCK_SIZE_LONG; i++) {
 -            float sum1, sum2;
 -            sum1 = firbuf[i + (PSY_LAME_FIR_LEN - 1) / 2];
 -            sum2 = 0.0;
 -            for (j = 0; j < ((PSY_LAME_FIR_LEN - 1) / 2) - 1; j += 2) {
 -                sum1 += psy_fir_coeffs[j] * (firbuf[i + j] + firbuf[i + PSY_LAME_FIR_LEN - j]);
 -                sum2 += psy_fir_coeffs[j + 1] * (firbuf[i + j + 1] + firbuf[i + PSY_LAME_FIR_LEN - j - 1]);
 -            }
 -            /* NOTE: The LAME psymodel expects its input in the range -32768 to
 -             * 32768. Tuning this for normalized floats would be difficult. */
 -            hpfsmpl[i] = (sum1 + sum2) * 32768.0f;
 -        }
 +        psy_hp_filter(firbuf, hpfsmpl, psy_fir_coeffs);
  
          /* Calculate the energies of each sub-shortblock */
          for (i = 0; i < PSY_LAME_NUM_SUBBLOCKS; i++) {
  
      wi.window_type[1] = prev_type;
      if (wi.window_type[0] != EIGHT_SHORT_SEQUENCE) {
 +
          wi.num_windows  = 1;
          wi.grouping[0]  = 1;
          if (wi.window_type[0] == LONG_START_SEQUENCE)
              wi.window_shape = 0;
          else
              wi.window_shape = 1;
 +
      } else {
          int lastgrp = 0;