Merge commit '43717469f9daa402f6acb48997255827a56034e9'
authorClément Bœsch <u@pkh.me>
Wed, 22 Mar 2017 10:11:28 +0000 (11:11 +0100)
committerClément Bœsch <u@pkh.me>
Wed, 22 Mar 2017 10:29:46 +0000 (11:29 +0100)
* commit '43717469f9daa402f6acb48997255827a56034e9':
  ac3dsp: Reverse matrix in/out order in downmix()

Merged-by: Clément Bœsch <u@pkh.me>
1  2 
libavcodec/ac3dec.c
libavcodec/ac3dec.h
libavcodec/ac3dec_fixed.c
libavcodec/ac3dsp.c
libavcodec/ac3dsp.h
libavcodec/x86/ac3dsp_init.c

@@@ -368,46 -338,51 +368,56 @@@ static int set_downmix_coeffs(AC3Decode
      float cmix = gain_levels[s->  center_mix_level];
      float smix = gain_levels[s->surround_mix_level];
      float norm0, norm1;
-     float downmix_coeffs[AC3_MAX_CHANNELS][2];
++    float downmix_coeffs[2][AC3_MAX_CHANNELS];
+     if (!s->downmix_coeffs[0]) {
 -        s->downmix_coeffs[0] = av_malloc(2 * AC3_MAX_CHANNELS *
 -                                         sizeof(**s->downmix_coeffs));
++        s->downmix_coeffs[0] = av_malloc_array(2 * AC3_MAX_CHANNELS,
++                                               sizeof(**s->downmix_coeffs));
+         if (!s->downmix_coeffs[0])
+             return AVERROR(ENOMEM);
+         s->downmix_coeffs[1] = s->downmix_coeffs[0] + AC3_MAX_CHANNELS;
+     }
  
      for (i = 0; i < s->fbw_channels; i++) {
-         downmix_coeffs[i][0] = gain_levels[ac3_default_coeffs[s->channel_mode][i][0]];
-         downmix_coeffs[i][1] = gain_levels[ac3_default_coeffs[s->channel_mode][i][1]];
 -        s->downmix_coeffs[0][i] = gain_levels[ac3_default_coeffs[s->channel_mode][i][0]];
 -        s->downmix_coeffs[1][i] = gain_levels[ac3_default_coeffs[s->channel_mode][i][1]];
++        downmix_coeffs[0][i] = gain_levels[ac3_default_coeffs[s->channel_mode][i][0]];
++        downmix_coeffs[1][i] = gain_levels[ac3_default_coeffs[s->channel_mode][i][1]];
      }
      if (s->channel_mode > 1 && s->channel_mode & 1) {
-         downmix_coeffs[1][0] = downmix_coeffs[1][1] = cmix;
 -        s->downmix_coeffs[0][1] = s->downmix_coeffs[1][1] = cmix;
++        downmix_coeffs[0][1] = downmix_coeffs[1][1] = cmix;
      }
      if (s->channel_mode == AC3_CHMODE_2F1R || s->channel_mode == AC3_CHMODE_3F1R) {
          int nf = s->channel_mode - 2;
-         downmix_coeffs[nf][0] = downmix_coeffs[nf][1] = smix * LEVEL_MINUS_3DB;
 -        s->downmix_coeffs[0][nf] = s->downmix_coeffs[1][nf] = smix * LEVEL_MINUS_3DB;
++        downmix_coeffs[0][nf] = downmix_coeffs[1][nf] = smix * LEVEL_MINUS_3DB;
      }
      if (s->channel_mode == AC3_CHMODE_2F2R || s->channel_mode == AC3_CHMODE_3F2R) {
          int nf = s->channel_mode - 4;
-         downmix_coeffs[nf][0] = downmix_coeffs[nf+1][1] = smix;
 -        s->downmix_coeffs[0][nf] = s->downmix_coeffs[1][nf+1] = smix;
++        downmix_coeffs[0][nf] = downmix_coeffs[1][nf+1] = smix;
      }
  
      /* renormalize */
      norm0 = norm1 = 0.0;
      for (i = 0; i < s->fbw_channels; i++) {
-         norm0 += downmix_coeffs[i][0];
-         norm1 += downmix_coeffs[i][1];
 -        norm0 += s->downmix_coeffs[0][i];
 -        norm1 += s->downmix_coeffs[1][i];
++        norm0 += downmix_coeffs[0][i];
++        norm1 += downmix_coeffs[1][i];
      }
      norm0 = 1.0f / norm0;
      norm1 = 1.0f / norm1;
      for (i = 0; i < s->fbw_channels; i++) {
-         downmix_coeffs[i][0] *= norm0;
-         downmix_coeffs[i][1] *= norm1;
 -        s->downmix_coeffs[0][i] *= norm0;
 -        s->downmix_coeffs[1][i] *= norm1;
++        downmix_coeffs[0][i] *= norm0;
++        downmix_coeffs[1][i] *= norm1;
      }
  
      if (s->output_mode == AC3_CHMODE_MONO) {
          for (i = 0; i < s->fbw_channels; i++)
-             downmix_coeffs[i][0] = (downmix_coeffs[i][0] +
-                                     downmix_coeffs[i][1]) * LEVEL_MINUS_3DB;
 -            s->downmix_coeffs[0][i] = (s->downmix_coeffs[0][i] +
 -                                       s->downmix_coeffs[1][i]) * LEVEL_MINUS_3DB;
++            downmix_coeffs[0][i] = (downmix_coeffs[0][i] +
++                                    downmix_coeffs[1][i]) * LEVEL_MINUS_3DB;
 +    }
 +    for (i = 0; i < s->fbw_channels; i++) {
-         s->downmix_coeffs[i][0] = FIXR12(downmix_coeffs[i][0]);
-         s->downmix_coeffs[i][1] = FIXR12(downmix_coeffs[i][1]);
++        s->downmix_coeffs[0][i] = FIXR12(downmix_coeffs[0][i]);
++        s->downmix_coeffs[1][i] = FIXR12(downmix_coeffs[1][i]);
      }
+     return 0;
  }
  
  /**
@@@ -1684,7 -1579,7 +1697,8 @@@ static av_cold int ac3_decode_end(AVCod
      AC3DecodeContext *s = avctx->priv_data;
      ff_mdct_end(&s->imdct_512);
      ff_mdct_end(&s->imdct_256);
 +    av_freep(&s->fdsp);
+     av_freep(&s->downmix_coeffs[0]);
  
      return 0;
  }
@@@ -159,7 -147,7 +159,7 @@@ typedef struct AC3DecodeContext 
      int fbw_channels;                           ///< number of full-bandwidth channels
      int channels;                               ///< number of total channels
      int lfe_ch;                                 ///< index of LFE channel
-     SHORTFLOAT downmix_coeffs[AC3_MAX_CHANNELS][2];  ///< stereo downmix coefficients
 -    float *downmix_coeffs[2];                   ///< stereo downmix coefficients
++    SHORTFLOAT *downmix_coeffs[2];              ///< stereo downmix coefficients
      int downmixed;                              ///< indicates if coeffs are currently downmixed
      int output_mode;                            ///< output channel configuration
      int out_channels;                           ///< number of output channels
index 1f79ade,0000000..682fe93
mode 100644,000000..100644
--- /dev/null
@@@ -1,197 -1,0 +1,197 @@@
- static void ac3_downmix_c_fixed16(int16_t **samples, int16_t (*matrix)[2],
 +/*
 + * Copyright (c) 2012
 + *      MIPS Technologies, Inc., California.
 + *
 + * Redistribution and use in source and binary forms, with or without
 + * modification, are permitted provided that the following conditions
 + * are met:
 + * 1. Redistributions of source code must retain the above copyright
 + *    notice, this list of conditions and the following disclaimer.
 + * 2. Redistributions in binary form must reproduce the above copyright
 + *    notice, this list of conditions and the following disclaimer in the
 + *    documentation and/or other materials provided with the distribution.
 + * 3. Neither the name of the MIPS Technologies, Inc., nor the names of its
 + *    contributors may be used to endorse or promote products derived from
 + *    this software without specific prior written permission.
 + *
 + * THIS SOFTWARE IS PROVIDED BY THE MIPS TECHNOLOGIES, INC. ``AS IS'' AND
 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 + * ARE DISCLAIMED.  IN NO EVENT SHALL THE MIPS TECHNOLOGIES, INC. BE LIABLE
 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 + * SUCH DAMAGE.
 + *
 + * Author:  Stanislav Ocovaj (socovaj@mips.com)
 + *
 + * AC3 fixed-point decoder for MIPS platforms
 + *
 + * This file is part of FFmpeg.
 + *
 + * 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.
 + *
 + * 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 FFmpeg; if not, write to the Free Software
 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 + */
 +
 +#define FFT_FLOAT 0
 +#define USE_FIXED 1
 +#define FFT_FIXED_32 1
 +#include "ac3dec.h"
 +
 +
 +static const int end_freq_inv_tab[8] =
 +{
 +    50529027, 44278013, 39403370, 32292987, 27356480, 23729101, 20951060, 18755316
 +};
 +
 +static void scale_coefs (
 +    int32_t *dst,
 +    const int32_t *src,
 +    int dynrng,
 +    int len)
 +{
 +    int i, shift, round;
 +    int16_t mul;
 +    int temp, temp1, temp2, temp3, temp4, temp5, temp6, temp7;
 +
 +    mul = (dynrng & 0x1f) + 0x20;
 +    shift = 4 - ((dynrng << 23) >> 28);
 +    if (shift > 0 ) {
 +      round = 1 << (shift-1);
 +      for (i=0; i<len; i+=8) {
 +
 +          temp = src[i] * mul;
 +          temp1 = src[i+1] * mul;
 +          temp = temp + round;
 +          temp2 = src[i+2] * mul;
 +
 +          temp1 = temp1 + round;
 +          dst[i] = temp >> shift;
 +          temp3 = src[i+3] * mul;
 +          temp2 = temp2 + round;
 +
 +          dst[i+1] = temp1 >> shift;
 +          temp4 = src[i + 4] * mul;
 +          temp3 = temp3 + round;
 +          dst[i+2] = temp2 >> shift;
 +
 +          temp5 = src[i+5] * mul;
 +          temp4 = temp4 + round;
 +          dst[i+3] = temp3 >> shift;
 +          temp6 = src[i+6] * mul;
 +
 +          dst[i+4] = temp4 >> shift;
 +          temp5 = temp5 + round;
 +          temp7 = src[i+7] * mul;
 +          temp6 = temp6 + round;
 +
 +          dst[i+5] = temp5 >> shift;
 +          temp7 = temp7 + round;
 +          dst[i+6] = temp6 >> shift;
 +          dst[i+7] = temp7 >> shift;
 +
 +      }
 +    } else {
 +      shift = -shift;
 +      for (i=0; i<len; i+=8) {
 +
 +          temp = src[i] * mul;
 +          temp1 = src[i+1] * mul;
 +          temp2 = src[i+2] * mul;
 +
 +          dst[i] = temp << shift;
 +          temp3 = src[i+3] * mul;
 +
 +          dst[i+1] = temp1 << shift;
 +          temp4 = src[i + 4] * mul;
 +          dst[i+2] = temp2 << shift;
 +
 +          temp5 = src[i+5] * mul;
 +          dst[i+3] = temp3 << shift;
 +          temp6 = src[i+6] * mul;
 +
 +          dst[i+4] = temp4 << shift;
 +          temp7 = src[i+7] * mul;
 +
 +          dst[i+5] = temp5 << shift;
 +          dst[i+6] = temp6 << shift;
 +          dst[i+7] = temp7 << shift;
 +
 +      }
 +    }
 +}
 +
 +/**
 + * Downmix samples from original signal to stereo or mono (this is for 16-bit samples
 + * and fixed point decoder - original (for 32-bit samples) is in ac3dsp.c).
 + */
-                 v0 += samples[j][i] * matrix[j][0];
-                 v1 += samples[j][i] * matrix[j][1];
++static void ac3_downmix_c_fixed16(int16_t **samples, int16_t **matrix,
 +                                  int out_ch, int in_ch, int len)
 +{
 +    int i, j;
 +    int v0, v1;
 +    if (out_ch == 2) {
 +        for (i = 0; i < len; i++) {
 +            v0 = v1 = 0;
 +            for (j = 0; j < in_ch; j++) {
-                 v0 += samples[j][i] * matrix[j][0];
++                v0 += samples[j][i] * matrix[0][j];
++                v1 += samples[j][i] * matrix[1][j];
 +            }
 +            samples[0][i] = (v0+2048)>>12;
 +            samples[1][i] = (v1+2048)>>12;
 +        }
 +    } else if (out_ch == 1) {
 +        for (i = 0; i < len; i++) {
 +            v0 = 0;
 +            for (j = 0; j < in_ch; j++)
++                v0 += samples[j][i] * matrix[0][j];
 +            samples[0][i] = (v0+2048)>>12;
 +        }
 +    }
 +}
 +
 +#include "eac3dec.c"
 +#include "ac3dec.c"
 +
 +static const AVOption options[] = {
 +    { "cons_noisegen", "enable consistent noise generation", OFFSET(consistent_noise_generation), AV_OPT_TYPE_BOOL, {.i64 = 0 }, 0, 1, PAR },
 +    { "drc_scale", "percentage of dynamic range compression to apply", OFFSET(drc_scale), AV_OPT_TYPE_FLOAT, {.dbl = 1.0}, 0.0, 6.0, PAR },
 +    { "heavy_compr", "enable heavy dynamic range compression", OFFSET(heavy_compression), AV_OPT_TYPE_BOOL, {.i64 = 0 }, 0, 1, PAR },
 +    { NULL},
 +};
 +
 +static const AVClass ac3_decoder_class = {
 +    .class_name = "Fixed-Point AC-3 Decoder",
 +    .item_name  = av_default_item_name,
 +    .option     = options,
 +    .version    = LIBAVUTIL_VERSION_INT,
 +};
 +
 +AVCodec ff_ac3_fixed_decoder = {
 +    .name           = "ac3_fixed",
 +    .type           = AVMEDIA_TYPE_AUDIO,
 +    .id             = AV_CODEC_ID_AC3,
 +    .priv_data_size = sizeof (AC3DecodeContext),
 +    .init           = ac3_decode_init,
 +    .close          = ac3_decode_end,
 +    .decode         = ac3_decode_frame,
 +    .capabilities   = AV_CODEC_CAP_DR1,
 +    .long_name      = NULL_IF_CONFIG_SMALL("ATSC A/52A (AC-3)"),
 +    .sample_fmts    = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16P,
 +                                                      AV_SAMPLE_FMT_NONE },
 +    .priv_class     = &ac3_decoder_class,
 +};
@@@ -171,49 -171,7 +171,49 @@@ static void ac3_extract_exponents_c(uin
      }
  }
  
- static void ac3_downmix_c(float **samples, float (*matrix)[2],
 +static void ac3_sum_square_butterfly_int32_c(int64_t sum[4],
 +                                             const int32_t *coef0,
 +                                             const int32_t *coef1,
 +                                             int len)
 +{
 +    int i;
 +
 +    sum[0] = sum[1] = sum[2] = sum[3] = 0;
 +
 +    for (i = 0; i < len; i++) {
 +        int lt = coef0[i];
 +        int rt = coef1[i];
 +        int md = lt + rt;
 +        int sd = lt - rt;
 +        MAC64(sum[0], lt, lt);
 +        MAC64(sum[1], rt, rt);
 +        MAC64(sum[2], md, md);
 +        MAC64(sum[3], sd, sd);
 +    }
 +}
 +
 +static void ac3_sum_square_butterfly_float_c(float sum[4],
 +                                             const float *coef0,
 +                                             const float *coef1,
 +                                             int len)
 +{
 +    int i;
 +
 +    sum[0] = sum[1] = sum[2] = sum[3] = 0;
 +
 +    for (i = 0; i < len; i++) {
 +        float lt = coef0[i];
 +        float rt = coef1[i];
 +        float md = lt + rt;
 +        float sd = lt - rt;
 +        sum[0] += lt * lt;
 +        sum[1] += rt * rt;
 +        sum[2] += md * md;
 +        sum[3] += sd * sd;
 +    }
 +}
 +
+ static void ac3_downmix_c(float **samples, float **matrix,
                            int out_ch, int in_ch, int len)
  {
      int i, j;
      }
  }
  
- static void ac3_downmix_c_fixed(int32_t **samples, int16_t (*matrix)[2],
++static void ac3_downmix_c_fixed(int32_t **samples, int16_t **matrix,
 +                                int out_ch, int in_ch, int len)
 +{
 +    int i, j;
 +    int64_t v0, v1;
 +    if (out_ch == 2) {
 +        for (i = 0; i < len; i++) {
 +            v0 = v1 = 0;
 +            for (j = 0; j < in_ch; j++) {
-                 v0 += (int64_t)samples[j][i] * matrix[j][0];
-                 v1 += (int64_t)samples[j][i] * matrix[j][1];
++                v0 += (int64_t)samples[j][i] * matrix[0][j];
++                v1 += (int64_t)samples[j][i] * matrix[1][j];
 +            }
 +            samples[0][i] = (v0+2048)>>12;
 +            samples[1][i] = (v1+2048)>>12;
 +        }
 +    } else if (out_ch == 1) {
 +        for (i = 0; i < len; i++) {
 +            v0 = 0;
 +            for (j = 0; j < in_ch; j++)
-                 v0 += (int64_t)samples[j][i] * matrix[j][0];
++                v0 += (int64_t)samples[j][i] * matrix[0][j];
 +            samples[0][i] = (v0+2048)>>12;
 +        }
 +    }
 +}
 +
  static void apply_window_int16_c(int16_t *output, const int16_t *input,
                                   const int16_t *window, unsigned int len)
  {
@@@ -126,18 -126,9 +126,18 @@@ typedef struct AC3DSPContext 
  
      void (*extract_exponents)(uint8_t *exp, int32_t *coef, int nb_coefs);
  
-     void (*downmix)(float **samples, float (*matrix)[2], int out_ch,
 +    void (*sum_square_butterfly_int32)(int64_t sum[4], const int32_t *coef0,
 +                                       const int32_t *coef1, int len);
 +
 +    void (*sum_square_butterfly_float)(float sum[4], const float *coef0,
 +                                       const float *coef1, int len);
 +
+     void (*downmix)(float **samples, float **matrix, int out_ch,
                      int in_ch, int len);
  
-     void (*downmix_fixed)(int32_t **samples, int16_t (*matrix)[2], int out_ch,
++    void (*downmix_fixed)(int32_t **samples, int16_t **matrix, int out_ch,
 +                          int in_ch, int len);
 +
      /**
       * Apply symmetric window in 16-bit fixed-point.
       * @param output destination array
@@@ -154,17 -149,17 +154,17 @@@ static void ac3_downmix_sse(float **sam
  
      i = -len * sizeof(float);
      if (in_ch == 5 && out_ch == 2 &&
-         !(matrix_cmp[0][1] | matrix_cmp[2][0]   |
-           matrix_cmp[3][1] | matrix_cmp[4][0]   |
-           (matrix_cmp[1][0] ^ matrix_cmp[1][1]) |
-           (matrix_cmp[0][0] ^ matrix_cmp[2][1]))) {
+         !(matrix_cmp[1][0] | matrix_cmp[0][2]   |
+           matrix_cmp[1][3] | matrix_cmp[0][4]   |
+           (matrix_cmp[0][1] ^ matrix_cmp[1][1]) |
+           (matrix_cmp[0][0] ^ matrix_cmp[1][2]))) {
          MIX5(IF0, IF1);
      } else if (in_ch == 5 && out_ch == 1 &&
-                matrix_cmp[0][0] == matrix_cmp[2][0] &&
-                matrix_cmp[3][0] == matrix_cmp[4][0]) {
+                matrix_cmp[0][0] == matrix_cmp[0][2] &&
+                matrix_cmp[0][3] == matrix_cmp[0][4]) {
          MIX5(IF1, IF0);
      } else {
 -        DECLARE_ALIGNED(16, float, matrix_simd)[AC3_MAX_CHANNELS][2][4];
 +        LOCAL_ALIGNED(16, float, matrix_simd, [AC3_MAX_CHANNELS], [2][4]);
          float *samp[AC3_MAX_CHANNELS];
  
          for (j = 0; j < in_ch; j++)