bug 1476231 add ffmpeg floating point real FFT functions to ffvpx when MOZ_LIBAV_FFT is configured r?jya draft
authorKarl Tomlinson <karlt+@karlt.net>
Sun, 15 Jul 2018 20:08:27 +1200
changeset 825589 2472986e87708cef8b43cd598175c913914abe85
parent 825588 2b158275727b8b79bda2aef67740f447412ec7a7
child 825590 ca35da82171facdf606443f6a0da7c0da000df36
push id118144
push userktomlinson@mozilla.com
push dateThu, 02 Aug 2018 02:57:58 +0000
reviewersjya
bugs1476231
milestone63.0a1
bug 1476231 add ffmpeg floating point real FFT functions to ffvpx when MOZ_LIBAV_FFT is configured r?jya New files are from ffmpeg n3.4-1-g587fadaef1. MozReview-Commit-ID: E9eLPySCpCz
media/ffvpx/config_common.h
media/ffvpx/libavcodec/avcodec.symbols
media/ffvpx/libavcodec/avfft.c
media/ffvpx/libavcodec/avfft.h
media/ffvpx/libavcodec/dct.h
media/ffvpx/libavcodec/dummy_funcs.c
media/ffvpx/libavcodec/fft-internal.h
media/ffvpx/libavcodec/fft.h
media/ffvpx/libavcodec/fft_float.c
media/ffvpx/libavcodec/fft_template.c
media/ffvpx/libavcodec/moz.build
media/ffvpx/libavcodec/rdft.c
media/ffvpx/libavcodec/rdft.h
media/ffvpx/libavcodec/x86/fft.asm
media/ffvpx/libavcodec/x86/fft.h
media/ffvpx/libavcodec/x86/fft_init.c
media/ffvpx/libavcodec/x86/moz.build
--- a/media/ffvpx/config_common.h
+++ b/media/ffvpx/config_common.h
@@ -6,9 +6,16 @@
 #undef HAVE_AVX2
 #undef HAVE_AVX2_INTERNAL
 #undef HAVE_AVX2_EXTERNAL
 #define HAVE_AVX2 0
 #define HAVE_AVX2_INTERNAL 0
 #define HAVE_AVX2_EXTERNAL 0
 #endif
 
+#ifdef MOZ_LIBAV_FFT
+#undef CONFIG_FFT
+#undef CONFIG_RDFT
+#define CONFIG_FFT 1
+#define CONFIG_RDFT 1
 #endif
+
+#endif
--- a/media/ffvpx/libavcodec/avcodec.symbols
+++ b/media/ffvpx/libavcodec/avcodec.symbols
@@ -48,16 +48,19 @@ av_packet_side_data_name
 av_packet_split_side_data
 av_packet_unpack_dictionary
 av_packet_unref
 av_parser_change
 av_parser_close
 av_parser_init
 av_parser_next
 av_parser_parse2
+av_rdft_calc
+av_rdft_end
+av_rdft_init
 av_register_codec_parser
 av_register_hwaccel
 av_shrink_packet
 av_vorbis_parse_frame
 av_vorbis_parse_frame_flags
 av_vorbis_parse_free
 av_vorbis_parse_init
 av_vorbis_parse_reset
copy from media/libav/libavcodec/avfft.c
copy to media/ffvpx/libavcodec/avfft.c
--- a/media/libav/libavcodec/avfft.c
+++ b/media/ffvpx/libavcodec/avfft.c
@@ -1,38 +1,38 @@
 /*
- * 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 "libavutil/attributes.h"
 #include "libavutil/mem.h"
 #include "avfft.h"
 #include "fft.h"
 #include "rdft.h"
 #include "dct.h"
 
 /* FFT */
 
 FFTContext *av_fft_init(int nbits, int inverse)
 {
-    FFTContext *s = av_malloc(sizeof(*s));
+    FFTContext *s = av_mallocz(sizeof(*s));
 
     if (s && ff_fft_init(s, nbits, inverse))
         av_freep(&s);
 
     return s;
 }
 
 void av_fft_permute(FFTContext *s, FFTComplex *z)
copy from media/libav/libavcodec/avfft.h
copy to media/ffvpx/libavcodec/avfft.h
--- a/media/libav/libavcodec/avfft.h
+++ b/media/ffvpx/libavcodec/avfft.h
@@ -1,23 +1,23 @@
 /*
- * 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
  */
 
 #ifndef AVCODEC_AVFFT_H
 #define AVCODEC_AVFFT_H
 
 /**
  * @file
copy from media/libav/libavcodec/dct.h
copy to media/ffvpx/libavcodec/dct.h
--- a/media/libav/libavcodec/dct.h
+++ b/media/ffvpx/libavcodec/dct.h
@@ -1,34 +1,35 @@
 /*
  * (I)DCT Transforms
  * Copyright (c) 2009 Peter Ross <pross@xvid.org>
  * Copyright (c) 2010 Alex Converse <alex.converse@gmail.com>
  * Copyright (c) 2010 Vitor Sessak
  *
- * 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 St, Fifth Floor, Boston, MA  02110-1301  USA
  */
 
-#ifndef AVCODEC_DCT_H
+#if !defined(AVCODEC_DCT_H) && (!defined(FFT_FLOAT) || FFT_FLOAT)
 #define AVCODEC_DCT_H
 
+#include <stddef.h>
 #include <stdint.h>
 
 #include "rdft.h"
 
 struct DCTContext {
     int nbits;
     int inverse;
     RDFTContext rdft;
@@ -54,10 +55,15 @@ void ff_dct_init_x86(DCTContext *s);
 void ff_fdct_ifast(int16_t *data);
 void ff_fdct_ifast248(int16_t *data);
 void ff_jpeg_fdct_islow_8(int16_t *data);
 void ff_jpeg_fdct_islow_10(int16_t *data);
 void ff_fdct248_islow_8(int16_t *data);
 void ff_fdct248_islow_10(int16_t *data);
 
 void ff_j_rev_dct(int16_t *data);
+void ff_j_rev_dct4(int16_t *data);
+void ff_j_rev_dct2(int16_t *data);
+void ff_j_rev_dct1(int16_t *data);
+void ff_jref_idct_put(uint8_t *dest, ptrdiff_t line_size, int16_t *block);
+void ff_jref_idct_add(uint8_t *dest, ptrdiff_t line_size, int16_t *block);
 
 #endif /* AVCODEC_DCT_H */
--- a/media/ffvpx/libavcodec/dummy_funcs.c
+++ b/media/ffvpx/libavcodec/dummy_funcs.c
@@ -1,17 +1,19 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim:set ts=2 sw=2 sts=2 et cindent: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "avcodec.h"
 
+typedef struct FFTContext FFTContext;
 typedef struct H264PredContext H264PredContext;
+typedef struct RDFTContext RDFTContext;
 typedef struct VideoDSPContext VideoDSPContext;
 typedef struct VP8DSPContext VP8DSPContext;
 typedef struct VP9DSPContext VP9DSPContext;
 typedef struct FLACDSPContext FLACDSPContext;
 
 AVHWAccel ff_h263_vaapi_hwaccel;
 AVHWAccel ff_h263_vdpau_hwaccel;
 AVHWAccel ff_h263_videotoolbox_hwaccel;
@@ -851,16 +853,21 @@ AVBitStreamFilter ff_mjpeg2jpeg_bsf;
 AVBitStreamFilter ff_mjpega_dump_header_bsf;
 AVBitStreamFilter ff_mp3_header_decompress_bsf;
 AVBitStreamFilter ff_mpeg4_unpack_bframes_bsf;
 AVBitStreamFilter ff_mov2textsub_bsf;
 AVBitStreamFilter ff_noise_bsf;
 AVBitStreamFilter ff_remove_extradata_bsf;
 AVBitStreamFilter ff_text2movsub_bsf;
 
+void ff_fft_init_aarch64(FFTContext *s) {}
+void ff_fft_init_arm(FFTContext *s) {}
+void ff_fft_init_mips(FFTContext *s) {}
+void ff_fft_init_ppc(FFTContext *s) {}
+void ff_rdft_init_arm(RDFTContext *s) {}
 void ff_h264_pred_init_aarch64(H264PredContext *h, int codec_id,
                                const int bit_depth,
                                const int chroma_format_idc) {}
 void ff_h264_pred_init_arm(H264PredContext *h, int codec_id,
                            const int bit_depth, const int chroma_format_idc) {}
 void ff_h264_pred_init_mips(H264PredContext *h, int codec_id,
                             const int bit_depth, const int chroma_format_idc) {}
 void ff_me_cmp_init_static(void) {}
copy from media/libav/libavcodec/fft-internal.h
copy to media/ffvpx/libavcodec/fft-internal.h
--- a/media/libav/libavcodec/fft-internal.h
+++ b/media/ffvpx/libavcodec/fft-internal.h
@@ -1,23 +1,23 @@
 /*
- * 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
  */
 
 #ifndef AVCODEC_FFT_INTERNAL_H
 #define AVCODEC_FFT_INTERNAL_H
 
 #if FFT_FLOAT
 
@@ -31,22 +31,39 @@
 
 #define CMUL(dre, dim, are, aim, bre, bim) do { \
         (dre) = (are) * (bre) - (aim) * (bim);  \
         (dim) = (are) * (bim) + (aim) * (bre);  \
     } while (0)
 
 #else
 
+#define SCALE_FLOAT(a, bits) lrint((a) * (double)(1 << (bits)))
+
+#if FFT_FIXED_32
+
+#define CMUL(dre, dim, are, aim, bre, bim) do {             \
+        int64_t accu;                                     \
+        (accu)  = (int64_t)(bre) * (are);                 \
+        (accu) -= (int64_t)(bim) * (aim);                 \
+        (dre)   = (int)(((accu) + 0x40000000) >> 31);       \
+        (accu)  = (int64_t)(bre) * (aim);                 \
+        (accu) += (int64_t)(bim) * (are);                 \
+        (dim)   = (int)(((accu) + 0x40000000) >> 31);       \
+    } while (0)
+
+#define FIX15(a) av_clip(SCALE_FLOAT(a, 31), -2147483647, 2147483647)
+
+#else /* FFT_FIXED_32 */
+
 #include "fft.h"
 #include "mathops.h"
 
 void ff_mdct_calcw_c(FFTContext *s, FFTDouble *output, const FFTSample *input);
 
-#define SCALE_FLOAT(a, bits) lrint((a) * (double)(1 << (bits)))
 #define FIX15(a) av_clip(SCALE_FLOAT(a, 15), -32767, 32767)
 
 #define sqrthalf ((int16_t)((1<<15)*M_SQRT1_2))
 
 #define BF(x, y, a, b) do {                     \
         x = (a - b) >> 1;                       \
         y = (a + b) >> 1;                       \
     } while (0)
@@ -57,16 +74,18 @@ void ff_mdct_calcw_c(FFTContext *s, FFTD
     } while (0)
 
 #define CMUL(dre, dim, are, aim, bre, bim)      \
     CMULS(dre, dim, are, aim, bre, bim, 15)
 
 #define CMULL(dre, dim, are, aim, bre, bim)     \
     CMULS(dre, dim, are, aim, bre, bim, 0)
 
+#endif /* FFT_FIXED_32 */
+
 #endif /* FFT_FLOAT */
 
 #define ff_imdct_calc_c FFT_NAME(ff_imdct_calc_c)
 #define ff_imdct_half_c FFT_NAME(ff_imdct_half_c)
 #define ff_mdct_calc_c  FFT_NAME(ff_mdct_calc_c)
 
 void ff_imdct_calc_c(FFTContext *s, FFTSample *output, const FFTSample *input);
 void ff_imdct_half_c(FFTContext *s, FFTSample *output, const FFTSample *input);
copy from media/libav/libavcodec/fft.h
copy to media/ffvpx/libavcodec/fft.h
--- a/media/libav/libavcodec/fft.h
+++ b/media/ffvpx/libavcodec/fft.h
@@ -1,59 +1,74 @@
 /*
  * Copyright (c) 2000, 2001, 2002 Fabrice Bellard
  * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
  *
- * 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
  */
 
 #ifndef AVCODEC_FFT_H
 #define AVCODEC_FFT_H
 
 #ifndef FFT_FLOAT
 #define FFT_FLOAT 1
 #endif
 
+#ifndef FFT_FIXED_32
+#define FFT_FIXED_32 0
+#endif
+
 #include <stdint.h>
 #include "config.h"
 #include "libavutil/mem.h"
 
 #if FFT_FLOAT
 
 #include "avfft.h"
 
 #define FFT_NAME(x) x
 
 typedef float FFTDouble;
 
 #else
 
+#if FFT_FIXED_32
+
+#define Q31(x) (int)((x)*2147483648.0 + 0.5)
+#define FFT_NAME(x) x ## _fixed_32
+
+typedef int32_t FFTSample;
+
+#else /* FFT_FIXED_32 */
+
 #define FFT_NAME(x) x ## _fixed
 
 typedef int16_t FFTSample;
-typedef int     FFTDouble;
+
+#endif /* FFT_FIXED_32 */
 
 typedef struct FFTComplex {
-    int16_t re, im;
+    FFTSample re, im;
 } FFTComplex;
 
+typedef int    FFTDouble;
 typedef struct FFTContext FFTContext;
 
 #endif /* FFT_FLOAT */
 
 typedef struct FFTDComplex {
     FFTDouble re, im;
 } FFTDComplex;
 
@@ -90,16 +105,17 @@ struct FFTContext {
      */
     void (*fft_calc)(struct FFTContext *s, FFTComplex *z);
     void (*imdct_calc)(struct FFTContext *s, FFTSample *output, const FFTSample *input);
     void (*imdct_half)(struct FFTContext *s, FFTSample *output, const FFTSample *input);
     void (*mdct_calc)(struct FFTContext *s, FFTSample *output, const FFTSample *input);
     void (*mdct_calcw)(struct FFTContext *s, FFTDouble *output, const FFTSample *input);
     enum fft_permutation_type fft_permutation;
     enum mdct_permutation_type mdct_permutation;
+    uint32_t *revtab32;
 };
 
 #if CONFIG_HARDCODED_TABLES
 #define COSTABLE_CONST const
 #else
 #define COSTABLE_CONST
 #endif
 
@@ -114,17 +130,18 @@ extern COSTABLE(256);
 extern COSTABLE(512);
 extern COSTABLE(1024);
 extern COSTABLE(2048);
 extern COSTABLE(4096);
 extern COSTABLE(8192);
 extern COSTABLE(16384);
 extern COSTABLE(32768);
 extern COSTABLE(65536);
-extern COSTABLE_CONST FFTSample* const FFT_NAME(ff_cos_tabs)[17];
+extern COSTABLE(131072);
+extern COSTABLE_CONST FFTSample* const FFT_NAME(ff_cos_tabs)[18];
 
 #define ff_init_ff_cos_tabs FFT_NAME(ff_init_ff_cos_tabs)
 
 /**
  * Initialize the cosine table in ff_cos_tabs[index]
  * @param index index in ff_cos_tabs array of the table to initialize
  */
 void ff_init_ff_cos_tabs(int index);
@@ -137,16 +154,17 @@ void ff_init_ff_cos_tabs(int index);
  * @param nbits           log2 of the length of the input array
  * @param inverse         if 0 perform the forward transform, if 1 perform the inverse
  */
 int ff_fft_init(FFTContext *s, int nbits, int inverse);
 
 void ff_fft_init_aarch64(FFTContext *s);
 void ff_fft_init_x86(FFTContext *s);
 void ff_fft_init_arm(FFTContext *s);
+void ff_fft_init_mips(FFTContext *s);
 void ff_fft_init_ppc(FFTContext *s);
 
 void ff_fft_fixed_init_arm(FFTContext *s);
 
 void ff_fft_end(FFTContext *s);
 
 #define ff_mdct_init FFT_NAME(ff_mdct_init)
 #define ff_mdct_end  FFT_NAME(ff_mdct_end)
copy from media/libav/libavcodec/fft_float.c
copy to media/ffvpx/libavcodec/fft_float.c
--- a/media/libav/libavcodec/fft_float.c
+++ b/media/ffvpx/libavcodec/fft_float.c
@@ -1,20 +1,21 @@
 /*
- * 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
  */
 
 #define FFT_FLOAT 1
+#define FFT_FIXED_32 0
 #include "fft_template.c"
copy from media/libav/libavcodec/fft_template.c
copy to media/ffvpx/libavcodec/fft_template.c
--- a/media/libav/libavcodec/fft_template.c
+++ b/media/ffvpx/libavcodec/fft_template.c
@@ -1,100 +1,169 @@
 /*
  * FFT/IFFT transforms
  * Copyright (c) 2008 Loren Merritt
  * Copyright (c) 2002 Fabrice Bellard
  * Partly based on libdjbfft by D. J. Bernstein
  *
- * 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
  */
 
 /**
  * @file
  * FFT/IFFT transforms.
  */
 
 #include <stdlib.h>
 #include <string.h>
 #include "libavutil/mathematics.h"
+#include "libavutil/thread.h"
 #include "fft.h"
 #include "fft-internal.h"
 
+#if FFT_FIXED_32
+#include "fft_table.h"
+
+static void av_cold fft_lut_init(void)
+{
+    int n = 0;
+    ff_fft_lut_init(ff_fft_offsets_lut, 0, 1 << 17, &n);
+}
+
+#else /* FFT_FIXED_32 */
+
 /* cos(2*pi*x/n) for 0<=x<=n/4, followed by its reverse */
 #if !CONFIG_HARDCODED_TABLES
 COSTABLE(16);
 COSTABLE(32);
 COSTABLE(64);
 COSTABLE(128);
 COSTABLE(256);
 COSTABLE(512);
 COSTABLE(1024);
 COSTABLE(2048);
 COSTABLE(4096);
 COSTABLE(8192);
 COSTABLE(16384);
 COSTABLE(32768);
 COSTABLE(65536);
+COSTABLE(131072);
+
+static av_cold void init_ff_cos_tabs(int index)
+{
+    int i;
+    int m = 1<<index;
+    double freq = 2*M_PI/m;
+    FFTSample *tab = FFT_NAME(ff_cos_tabs)[index];
+    for(i=0; i<=m/4; i++)
+        tab[i] = FIX15(cos(i*freq));
+    for(i=1; i<m/4; i++)
+        tab[m/2-i] = tab[i];
+}
+
+typedef struct CosTabsInitOnce {
+    void (*func)(void);
+    AVOnce control;
+} CosTabsInitOnce;
+
+#define INIT_FF_COS_TABS_FUNC(index, size)          \
+static av_cold void init_ff_cos_tabs_ ## size (void)\
+{                                                   \
+    init_ff_cos_tabs(index);                        \
+}
+
+INIT_FF_COS_TABS_FUNC(4, 16)
+INIT_FF_COS_TABS_FUNC(5, 32)
+INIT_FF_COS_TABS_FUNC(6, 64)
+INIT_FF_COS_TABS_FUNC(7, 128)
+INIT_FF_COS_TABS_FUNC(8, 256)
+INIT_FF_COS_TABS_FUNC(9, 512)
+INIT_FF_COS_TABS_FUNC(10, 1024)
+INIT_FF_COS_TABS_FUNC(11, 2048)
+INIT_FF_COS_TABS_FUNC(12, 4096)
+INIT_FF_COS_TABS_FUNC(13, 8192)
+INIT_FF_COS_TABS_FUNC(14, 16384)
+INIT_FF_COS_TABS_FUNC(15, 32768)
+INIT_FF_COS_TABS_FUNC(16, 65536)
+INIT_FF_COS_TABS_FUNC(17, 131072)
+
+static CosTabsInitOnce cos_tabs_init_once[] = {
+    { NULL },
+    { NULL },
+    { NULL },
+    { NULL },
+    { init_ff_cos_tabs_16, AV_ONCE_INIT },
+    { init_ff_cos_tabs_32, AV_ONCE_INIT },
+    { init_ff_cos_tabs_64, AV_ONCE_INIT },
+    { init_ff_cos_tabs_128, AV_ONCE_INIT },
+    { init_ff_cos_tabs_256, AV_ONCE_INIT },
+    { init_ff_cos_tabs_512, AV_ONCE_INIT },
+    { init_ff_cos_tabs_1024, AV_ONCE_INIT },
+    { init_ff_cos_tabs_2048, AV_ONCE_INIT },
+    { init_ff_cos_tabs_4096, AV_ONCE_INIT },
+    { init_ff_cos_tabs_8192, AV_ONCE_INIT },
+    { init_ff_cos_tabs_16384, AV_ONCE_INIT },
+    { init_ff_cos_tabs_32768, AV_ONCE_INIT },
+    { init_ff_cos_tabs_65536, AV_ONCE_INIT },
+    { init_ff_cos_tabs_131072, AV_ONCE_INIT },
+};
+
 #endif
 COSTABLE_CONST FFTSample * const FFT_NAME(ff_cos_tabs)[] = {
     NULL, NULL, NULL, NULL,
     FFT_NAME(ff_cos_16),
     FFT_NAME(ff_cos_32),
     FFT_NAME(ff_cos_64),
     FFT_NAME(ff_cos_128),
     FFT_NAME(ff_cos_256),
     FFT_NAME(ff_cos_512),
     FFT_NAME(ff_cos_1024),
     FFT_NAME(ff_cos_2048),
     FFT_NAME(ff_cos_4096),
     FFT_NAME(ff_cos_8192),
     FFT_NAME(ff_cos_16384),
     FFT_NAME(ff_cos_32768),
     FFT_NAME(ff_cos_65536),
+    FFT_NAME(ff_cos_131072),
 };
 
+#endif /* FFT_FIXED_32 */
+
 static void fft_permute_c(FFTContext *s, FFTComplex *z);
 static void fft_calc_c(FFTContext *s, FFTComplex *z);
 
 static int split_radix_permutation(int i, int n, int inverse)
 {
     int m;
     if(n <= 2) return i&1;
     m = n >> 1;
     if(!(i&m))            return split_radix_permutation(i, m, inverse)*2;
     m >>= 1;
     if(inverse == !(i&m)) return split_radix_permutation(i, m, inverse)*4 + 1;
     else                  return split_radix_permutation(i, m, inverse)*4 - 1;
 }
 
 av_cold void ff_init_ff_cos_tabs(int index)
 {
-#if !CONFIG_HARDCODED_TABLES
-    int i;
-    int m = 1<<index;
-    double freq = 2*M_PI/m;
-    FFTSample *tab = FFT_NAME(ff_cos_tabs)[index];
-    for(i=0; i<=m/4; i++)
-        tab[i] = FIX15(cos(i*freq));
-    for(i=1; i<m/4; i++)
-        tab[m/2-i] = tab[i];
+#if (!CONFIG_HARDCODED_TABLES) && (!FFT_FIXED_32)
+    ff_thread_once(&cos_tabs_init_once[index].control, cos_tabs_init_once[index].func);
 #endif
 }
 
 static const int avx_tab[] = {
     0, 4, 1, 5, 8, 12, 9, 13, 2, 6, 3, 7, 10, 14, 11, 15
 };
 
 static int is_second_half_of_fft32(int i, int n)
@@ -130,87 +199,276 @@ static av_cold void fft_perm_avx(FFTCont
         }
     }
 }
 
 av_cold int ff_fft_init(FFTContext *s, int nbits, int inverse)
 {
     int i, j, n;
 
-    if (nbits < 2 || nbits > 16)
+    s->revtab = NULL;
+    s->revtab32 = NULL;
+
+    if (nbits < 2 || nbits > 17)
         goto fail;
     s->nbits = nbits;
     n = 1 << nbits;
 
-    s->revtab = av_malloc(n * sizeof(uint16_t));
-    if (!s->revtab)
-        goto fail;
+    if (nbits <= 16) {
+        s->revtab = av_malloc(n * sizeof(uint16_t));
+        if (!s->revtab)
+            goto fail;
+    } else {
+        s->revtab32 = av_malloc(n * sizeof(uint32_t));
+        if (!s->revtab32)
+            goto fail;
+    }
     s->tmp_buf = av_malloc(n * sizeof(FFTComplex));
     if (!s->tmp_buf)
         goto fail;
     s->inverse = inverse;
     s->fft_permutation = FF_FFT_PERM_DEFAULT;
 
     s->fft_permute = fft_permute_c;
     s->fft_calc    = fft_calc_c;
 #if CONFIG_MDCT
     s->imdct_calc  = ff_imdct_calc_c;
     s->imdct_half  = ff_imdct_half_c;
     s->mdct_calc   = ff_mdct_calc_c;
 #endif
 
+#if FFT_FIXED_32
+    {
+        static AVOnce control = AV_ONCE_INIT;
+        ff_thread_once(&control, fft_lut_init);
+    }
+#else /* FFT_FIXED_32 */
 #if FFT_FLOAT
     if (ARCH_AARCH64) ff_fft_init_aarch64(s);
     if (ARCH_ARM)     ff_fft_init_arm(s);
     if (ARCH_PPC)     ff_fft_init_ppc(s);
     if (ARCH_X86)     ff_fft_init_x86(s);
     if (CONFIG_MDCT)  s->mdct_calcw = s->mdct_calc;
+    if (HAVE_MIPSFPU) ff_fft_init_mips(s);
 #else
     if (CONFIG_MDCT)  s->mdct_calcw = ff_mdct_calcw_c;
     if (ARCH_ARM)     ff_fft_fixed_init_arm(s);
 #endif
-
     for(j=4; j<=nbits; j++) {
         ff_init_ff_cos_tabs(j);
     }
+#endif /* FFT_FIXED_32 */
+
 
     if (s->fft_permutation == FF_FFT_PERM_AVX) {
         fft_perm_avx(s);
     } else {
         for(i=0; i<n; i++) {
-            int j = i;
+            int k;
+            j = i;
             if (s->fft_permutation == FF_FFT_PERM_SWAP_LSBS)
                 j = (j&~3) | ((j>>1)&1) | ((j<<1)&2);
-            s->revtab[-split_radix_permutation(i, n, s->inverse) & (n-1)] = j;
+            k = -split_radix_permutation(i, n, s->inverse) & (n-1);
+            if (s->revtab)
+                s->revtab[k] = j;
+            if (s->revtab32)
+                s->revtab32[k] = j;
         }
     }
 
     return 0;
  fail:
     av_freep(&s->revtab);
+    av_freep(&s->revtab32);
     av_freep(&s->tmp_buf);
     return -1;
 }
 
 static void fft_permute_c(FFTContext *s, FFTComplex *z)
 {
     int j, np;
     const uint16_t *revtab = s->revtab;
+    const uint32_t *revtab32 = s->revtab32;
     np = 1 << s->nbits;
     /* TODO: handle split-radix permute in a more optimal way, probably in-place */
-    for(j=0;j<np;j++) s->tmp_buf[revtab[j]] = z[j];
+    if (revtab) {
+        for(j=0;j<np;j++) s->tmp_buf[revtab[j]] = z[j];
+    } else
+        for(j=0;j<np;j++) s->tmp_buf[revtab32[j]] = z[j];
+
     memcpy(z, s->tmp_buf, np * sizeof(FFTComplex));
 }
 
 av_cold void ff_fft_end(FFTContext *s)
 {
     av_freep(&s->revtab);
+    av_freep(&s->revtab32);
     av_freep(&s->tmp_buf);
 }
 
+#if FFT_FIXED_32
+
+static void fft_calc_c(FFTContext *s, FFTComplex *z) {
+
+    int nbits, i, n, num_transforms, offset, step;
+    int n4, n2, n34;
+    unsigned tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8;
+    FFTComplex *tmpz;
+    const int fft_size = (1 << s->nbits);
+    int64_t accu;
+
+    num_transforms = (0x2aab >> (16 - s->nbits)) | 1;
+
+    for (n=0; n<num_transforms; n++){
+        offset = ff_fft_offsets_lut[n] << 2;
+        tmpz = z + offset;
+
+        tmp1 = tmpz[0].re + (unsigned)tmpz[1].re;
+        tmp5 = tmpz[2].re + (unsigned)tmpz[3].re;
+        tmp2 = tmpz[0].im + (unsigned)tmpz[1].im;
+        tmp6 = tmpz[2].im + (unsigned)tmpz[3].im;
+        tmp3 = tmpz[0].re - (unsigned)tmpz[1].re;
+        tmp8 = tmpz[2].im - (unsigned)tmpz[3].im;
+        tmp4 = tmpz[0].im - (unsigned)tmpz[1].im;
+        tmp7 = tmpz[2].re - (unsigned)tmpz[3].re;
+
+        tmpz[0].re = tmp1 + tmp5;
+        tmpz[2].re = tmp1 - tmp5;
+        tmpz[0].im = tmp2 + tmp6;
+        tmpz[2].im = tmp2 - tmp6;
+        tmpz[1].re = tmp3 + tmp8;
+        tmpz[3].re = tmp3 - tmp8;
+        tmpz[1].im = tmp4 - tmp7;
+        tmpz[3].im = tmp4 + tmp7;
+    }
+
+    if (fft_size < 8)
+        return;
+
+    num_transforms = (num_transforms >> 1) | 1;
+
+    for (n=0; n<num_transforms; n++){
+        offset = ff_fft_offsets_lut[n] << 3;
+        tmpz = z + offset;
+
+        tmp1 = tmpz[4].re + (unsigned)tmpz[5].re;
+        tmp3 = tmpz[6].re + (unsigned)tmpz[7].re;
+        tmp2 = tmpz[4].im + (unsigned)tmpz[5].im;
+        tmp4 = tmpz[6].im + (unsigned)tmpz[7].im;
+        tmp5 = tmp1 + tmp3;
+        tmp7 = tmp1 - tmp3;
+        tmp6 = tmp2 + tmp4;
+        tmp8 = tmp2 - tmp4;
+
+        tmp1 = tmpz[4].re - (unsigned)tmpz[5].re;
+        tmp2 = tmpz[4].im - (unsigned)tmpz[5].im;
+        tmp3 = tmpz[6].re - (unsigned)tmpz[7].re;
+        tmp4 = tmpz[6].im - (unsigned)tmpz[7].im;
+
+        tmpz[4].re = tmpz[0].re - tmp5;
+        tmpz[0].re = tmpz[0].re + tmp5;
+        tmpz[4].im = tmpz[0].im - tmp6;
+        tmpz[0].im = tmpz[0].im + tmp6;
+        tmpz[6].re = tmpz[2].re - tmp8;
+        tmpz[2].re = tmpz[2].re + tmp8;
+        tmpz[6].im = tmpz[2].im + tmp7;
+        tmpz[2].im = tmpz[2].im - tmp7;
+
+        accu = (int64_t)Q31(M_SQRT1_2)*(int)(tmp1 + tmp2);
+        tmp5 = (int32_t)((accu + 0x40000000) >> 31);
+        accu = (int64_t)Q31(M_SQRT1_2)*(int)(tmp3 - tmp4);
+        tmp7 = (int32_t)((accu + 0x40000000) >> 31);
+        accu = (int64_t)Q31(M_SQRT1_2)*(int)(tmp2 - tmp1);
+        tmp6 = (int32_t)((accu + 0x40000000) >> 31);
+        accu = (int64_t)Q31(M_SQRT1_2)*(int)(tmp3 + tmp4);
+        tmp8 = (int32_t)((accu + 0x40000000) >> 31);
+        tmp1 = tmp5 + tmp7;
+        tmp3 = tmp5 - tmp7;
+        tmp2 = tmp6 + tmp8;
+        tmp4 = tmp6 - tmp8;
+
+        tmpz[5].re = tmpz[1].re - tmp1;
+        tmpz[1].re = tmpz[1].re + tmp1;
+        tmpz[5].im = tmpz[1].im - tmp2;
+        tmpz[1].im = tmpz[1].im + tmp2;
+        tmpz[7].re = tmpz[3].re - tmp4;
+        tmpz[3].re = tmpz[3].re + tmp4;
+        tmpz[7].im = tmpz[3].im + tmp3;
+        tmpz[3].im = tmpz[3].im - tmp3;
+    }
+
+    step = 1 << ((MAX_LOG2_NFFT-4) - 4);
+    n4 = 4;
+
+    for (nbits=4; nbits<=s->nbits; nbits++){
+        n2  = 2*n4;
+        n34 = 3*n4;
+        num_transforms = (num_transforms >> 1) | 1;
+
+        for (n=0; n<num_transforms; n++){
+            const FFTSample *w_re_ptr = ff_w_tab_sr + step;
+            const FFTSample *w_im_ptr = ff_w_tab_sr + MAX_FFT_SIZE/(4*16) - step;
+            offset = ff_fft_offsets_lut[n] << nbits;
+            tmpz = z + offset;
+
+            tmp5 = tmpz[ n2].re + (unsigned)tmpz[n34].re;
+            tmp1 = tmpz[ n2].re - (unsigned)tmpz[n34].re;
+            tmp6 = tmpz[ n2].im + (unsigned)tmpz[n34].im;
+            tmp2 = tmpz[ n2].im - (unsigned)tmpz[n34].im;
+
+            tmpz[ n2].re = tmpz[ 0].re - tmp5;
+            tmpz[  0].re = tmpz[ 0].re + tmp5;
+            tmpz[ n2].im = tmpz[ 0].im - tmp6;
+            tmpz[  0].im = tmpz[ 0].im + tmp6;
+            tmpz[n34].re = tmpz[n4].re - tmp2;
+            tmpz[ n4].re = tmpz[n4].re + tmp2;
+            tmpz[n34].im = tmpz[n4].im + tmp1;
+            tmpz[ n4].im = tmpz[n4].im - tmp1;
+
+            for (i=1; i<n4; i++){
+                FFTSample w_re = w_re_ptr[0];
+                FFTSample w_im = w_im_ptr[0];
+                accu  = (int64_t)w_re*tmpz[ n2+i].re;
+                accu += (int64_t)w_im*tmpz[ n2+i].im;
+                tmp1 = (int32_t)((accu + 0x40000000) >> 31);
+                accu  = (int64_t)w_re*tmpz[ n2+i].im;
+                accu -= (int64_t)w_im*tmpz[ n2+i].re;
+                tmp2 = (int32_t)((accu + 0x40000000) >> 31);
+                accu  = (int64_t)w_re*tmpz[n34+i].re;
+                accu -= (int64_t)w_im*tmpz[n34+i].im;
+                tmp3 = (int32_t)((accu + 0x40000000) >> 31);
+                accu  = (int64_t)w_re*tmpz[n34+i].im;
+                accu += (int64_t)w_im*tmpz[n34+i].re;
+                tmp4 = (int32_t)((accu + 0x40000000) >> 31);
+
+                tmp5 = tmp1 + tmp3;
+                tmp1 = tmp1 - tmp3;
+                tmp6 = tmp2 + tmp4;
+                tmp2 = tmp2 - tmp4;
+
+                tmpz[ n2+i].re = tmpz[   i].re - tmp5;
+                tmpz[    i].re = tmpz[   i].re + tmp5;
+                tmpz[ n2+i].im = tmpz[   i].im - tmp6;
+                tmpz[    i].im = tmpz[   i].im + tmp6;
+                tmpz[n34+i].re = tmpz[n4+i].re - tmp2;
+                tmpz[ n4+i].re = tmpz[n4+i].re + tmp2;
+                tmpz[n34+i].im = tmpz[n4+i].im + tmp1;
+                tmpz[ n4+i].im = tmpz[n4+i].im - tmp1;
+
+                w_re_ptr += step;
+                w_im_ptr -= step;
+            }
+        }
+        step >>= 1;
+        n4   <<= 1;
+    }
+}
+
+#else /* FFT_FIXED_32 */
+
 #define BUTTERFLIES(a0,a1,a2,a3) {\
     BF(t3, t5, t5, t1);\
     BF(a2.re, a0.re, a0.re, t5);\
     BF(a3.im, a1.im, a1.im, t3);\
     BF(t4, t6, t2, t6);\
     BF(a3.re, a1.re, a1.re, t4);\
     BF(a2.im, a0.im, a0.im, t6);\
 }
@@ -336,18 +594,20 @@ DECL_FFT(512,256,128)
 #endif
 DECL_FFT(1024,512,256)
 DECL_FFT(2048,1024,512)
 DECL_FFT(4096,2048,1024)
 DECL_FFT(8192,4096,2048)
 DECL_FFT(16384,8192,4096)
 DECL_FFT(32768,16384,8192)
 DECL_FFT(65536,32768,16384)
+DECL_FFT(131072,65536,32768)
 
 static void (* const fft_dispatch[])(FFTComplex*) = {
     fft4, fft8, fft16, fft32, fft64, fft128, fft256, fft512, fft1024,
-    fft2048, fft4096, fft8192, fft16384, fft32768, fft65536,
+    fft2048, fft4096, fft8192, fft16384, fft32768, fft65536, fft131072
 };
 
 static void fft_calc_c(FFTContext *s, FFTComplex *z)
 {
     fft_dispatch[s->nbits-2](z);
 }
+#endif /* FFT_FIXED_32 */
--- a/media/ffvpx/libavcodec/moz.build
+++ b/media/ffvpx/libavcodec/moz.build
@@ -67,16 +67,23 @@ if not CONFIG['MOZ_FFVPX_FLACONLY']:
         'vp9dsp_12bpp.c',
         'vp9dsp_8bpp.c',
         'vp9lpf.c',
         'vp9mvs.c',
         'vp9prob.c',
         'vp9recon.c'
     ]
 
+if CONFIG['MOZ_LIBAV_FFT']:
+    SOURCES += [
+        'avfft.c',
+        'fft_float.c',
+        'rdft.c',
+    ]
+
 SYMBOLS_FILE = 'avcodec.symbols'
 NoVisibilityFlags()
 
 USE_LIBS += [
      'mozavutil'
 ]
 
 if CONFIG['OS_TARGET'] != 'WINNT':
copy from media/libav/libavcodec/rdft.c
copy to media/ffvpx/libavcodec/rdft.c
--- a/media/libav/libavcodec/rdft.c
+++ b/media/ffvpx/libavcodec/rdft.c
@@ -1,130 +1,114 @@
 /*
  * (I)RDFT transforms
  * Copyright (c) 2009 Alex Converse <alex dot converse at gmail dot 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 <stdlib.h>
 #include <math.h>
 #include "libavutil/mathematics.h"
 #include "rdft.h"
 
 /**
  * @file
  * (Inverse) Real Discrete Fourier Transforms.
  */
 
-/* sin(2*pi*x/n) for 0<=x<n/4, followed by n/2<=x<3n/4 */
-#if !CONFIG_HARDCODED_TABLES
-SINTABLE(16);
-SINTABLE(32);
-SINTABLE(64);
-SINTABLE(128);
-SINTABLE(256);
-SINTABLE(512);
-SINTABLE(1024);
-SINTABLE(2048);
-SINTABLE(4096);
-SINTABLE(8192);
-SINTABLE(16384);
-SINTABLE(32768);
-SINTABLE(65536);
-#endif
-static SINTABLE_CONST FFTSample * const ff_sin_tabs[] = {
-    NULL, NULL, NULL, NULL,
-    ff_sin_16, ff_sin_32, ff_sin_64, ff_sin_128, ff_sin_256, ff_sin_512, ff_sin_1024,
-    ff_sin_2048, ff_sin_4096, ff_sin_8192, ff_sin_16384, ff_sin_32768, ff_sin_65536,
-};
-
 /** Map one real FFT into two parallel real even and odd FFTs. Then interleave
  * the two real FFTs into one complex FFT. Unmangle the results.
  * ref: http://www.engineeringproductivitytools.com/stuff/T0001/PT10.HTM
  */
 static void rdft_calc_c(RDFTContext *s, FFTSample *data)
 {
     int i, i1, i2;
-    FFTComplex ev, od;
+    FFTComplex ev, od, odsum;
     const int n = 1 << s->nbits;
     const float k1 = 0.5;
     const float k2 = 0.5 - s->inverse;
     const FFTSample *tcos = s->tcos;
     const FFTSample *tsin = s->tsin;
 
     if (!s->inverse) {
         s->fft.fft_permute(&s->fft, (FFTComplex*)data);
         s->fft.fft_calc(&s->fft, (FFTComplex*)data);
     }
     /* i=0 is a special case because of packing, the DC term is real, so we
        are going to throw the N/2 term (also real) in with it. */
     ev.re = data[0];
     data[0] = ev.re+data[1];
     data[1] = ev.re-data[1];
-    for (i = 1; i < (n>>2); i++) {
-        i1 = 2*i;
-        i2 = n-i1;
-        /* Separate even and odd FFTs */
-        ev.re =  k1*(data[i1  ]+data[i2  ]);
-        od.im = -k2*(data[i1  ]-data[i2  ]);
-        ev.im =  k1*(data[i1+1]-data[i2+1]);
-        od.re =  k2*(data[i1+1]+data[i2+1]);
-        /* Apply twiddle factors to the odd FFT and add to the even FFT */
-        data[i1  ] =  ev.re + od.re*tcos[i] - od.im*tsin[i];
-        data[i1+1] =  ev.im + od.im*tcos[i] + od.re*tsin[i];
-        data[i2  ] =  ev.re - od.re*tcos[i] + od.im*tsin[i];
-        data[i2+1] = -ev.im + od.im*tcos[i] + od.re*tsin[i];
+
+#define RDFT_UNMANGLE(sign0, sign1)                                         \
+    for (i = 1; i < (n>>2); i++) {                                          \
+        i1 = 2*i;                                                           \
+        i2 = n-i1;                                                          \
+        /* Separate even and odd FFTs */                                    \
+        ev.re =  k1*(data[i1  ]+data[i2  ]);                                \
+        od.im =  k2*(data[i2  ]-data[i1  ]);                                \
+        ev.im =  k1*(data[i1+1]-data[i2+1]);                                \
+        od.re =  k2*(data[i1+1]+data[i2+1]);                                \
+        /* Apply twiddle factors to the odd FFT and add to the even FFT */  \
+        odsum.re = od.re*tcos[i] sign0 od.im*tsin[i];                       \
+        odsum.im = od.im*tcos[i] sign1 od.re*tsin[i];                       \
+        data[i1  ] =  ev.re + odsum.re;                                     \
+        data[i1+1] =  ev.im + odsum.im;                                     \
+        data[i2  ] =  ev.re - odsum.re;                                     \
+        data[i2+1] =  odsum.im - ev.im;                                     \
     }
+
+    if (s->negative_sin) {
+        RDFT_UNMANGLE(+,-)
+    } else {
+        RDFT_UNMANGLE(-,+)
+    }
+
     data[2*i+1]=s->sign_convention*data[2*i+1];
     if (s->inverse) {
         data[0] *= k1;
         data[1] *= k1;
         s->fft.fft_permute(&s->fft, (FFTComplex*)data);
         s->fft.fft_calc(&s->fft, (FFTComplex*)data);
     }
 }
 
 av_cold int ff_rdft_init(RDFTContext *s, int nbits, enum RDFTransformType trans)
 {
     int n = 1 << nbits;
-    int i;
-    const double theta = (trans == DFT_R2C || trans == DFT_C2R ? -1 : 1)*2*M_PI/n;
+    int ret;
 
     s->nbits           = nbits;
     s->inverse         = trans == IDFT_C2R || trans == DFT_C2R;
     s->sign_convention = trans == IDFT_R2C || trans == DFT_C2R ? 1 : -1;
+    s->negative_sin    = trans == DFT_C2R || trans == DFT_R2C;
 
     if (nbits < 4 || nbits > 16)
-        return -1;
+        return AVERROR(EINVAL);
 
-    if (ff_fft_init(&s->fft, nbits-1, trans == IDFT_C2R || trans == IDFT_R2C) < 0)
-        return -1;
+    if ((ret = ff_fft_init(&s->fft, nbits-1, trans == IDFT_C2R || trans == IDFT_R2C)) < 0)
+        return ret;
 
     ff_init_ff_cos_tabs(nbits);
     s->tcos = ff_cos_tabs[nbits];
-    s->tsin = ff_sin_tabs[nbits]+(trans == DFT_R2C || trans == DFT_C2R)*(n>>2);
-#if !CONFIG_HARDCODED_TABLES
-    for (i = 0; i < (n>>2); i++) {
-        s->tsin[i] = sin(i*theta);
-    }
-#endif
+    s->tsin = ff_cos_tabs[nbits] + (n >> 2);
     s->rdft_calc   = rdft_calc_c;
 
     if (ARCH_ARM) ff_rdft_init_arm(s);
 
     return 0;
 }
 
 av_cold void ff_rdft_end(RDFTContext *s)
copy from media/libav/libavcodec/rdft.h
copy to media/ffvpx/libavcodec/rdft.h
--- a/media/libav/libavcodec/rdft.h
+++ b/media/ffvpx/libavcodec/rdft.h
@@ -1,66 +1,44 @@
 /*
  * (I)RDFT transforms
  * Copyright (c) 2009 Alex Converse <alex dot converse at gmail dot 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
  */
 
-#ifndef AVCODEC_RDFT_H
+#if !defined(AVCODEC_RDFT_H) && (!defined(FFT_FLOAT) || FFT_FLOAT)
 #define AVCODEC_RDFT_H
 
 #include "config.h"
 #include "fft.h"
 
-#if CONFIG_HARDCODED_TABLES
-#   define SINTABLE_CONST const
-#else
-#   define SINTABLE_CONST
-#endif
-
-#define SINTABLE(size) \
-    SINTABLE_CONST DECLARE_ALIGNED(16, FFTSample, ff_sin_##size)[size/2]
-
-extern SINTABLE(16);
-extern SINTABLE(32);
-extern SINTABLE(64);
-extern SINTABLE(128);
-extern SINTABLE(256);
-extern SINTABLE(512);
-extern SINTABLE(1024);
-extern SINTABLE(2048);
-extern SINTABLE(4096);
-extern SINTABLE(8192);
-extern SINTABLE(16384);
-extern SINTABLE(32768);
-extern SINTABLE(65536);
-
 struct RDFTContext {
     int nbits;
     int inverse;
     int sign_convention;
 
     /* pre/post rotation tables */
     const FFTSample *tcos;
-    SINTABLE_CONST FFTSample *tsin;
+    const FFTSample *tsin;
+    int negative_sin;
     FFTContext fft;
     void (*rdft_calc)(struct RDFTContext *s, FFTSample *z);
 };
 
 /**
  * Set up a real FFT.
  * @param nbits           log2 of the length of the input array
  * @param trans           the type of transform
copy from media/libav/libavcodec/x86/fft.asm
copy to media/ffvpx/libavcodec/x86/fft.asm
--- a/media/libav/libavcodec/x86/fft.asm
+++ b/media/ffvpx/libavcodec/x86/fft.asm
@@ -1,30 +1,30 @@
 ;******************************************************************************
 ;* FFT transform with SSE/3DNow optimizations
 ;* Copyright (c) 2008 Loren Merritt
 ;* Copyright (c) 2011 Vitor Sessak
 ;*
 ;* This algorithm (though not any of the implementation details) is
 ;* based on libdjbfft by D. J. Bernstein.
 ;*
-;* 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
 ;******************************************************************************
 
 ; These functions are not individually interchangeable with the C versions.
 ; While C takes arrays of FFTComplex, SSE/3DNow leave intermediate results
 ; in blocks as conventient to the vector size.
 ; i.e. {4x real, 4x imaginary, 4x real, ...} (or 2x respectively)
 
@@ -46,56 +46,56 @@ struc FFTContext
     .tcos:     pointer 1
     .tsin:     pointer 1
     .fftperm:  pointer 1
     .fftcalc:  pointer 1
     .imdctcalc:pointer 1
     .imdcthalf:pointer 1
 endstruc
 
-SECTION_RODATA
+SECTION_RODATA 32
 
 %define M_SQRT1_2 0.70710678118654752440
 %define M_COS_PI_1_8 0.923879532511287
 %define M_COS_PI_3_8 0.38268343236509
 
-align 32
 ps_cos16_1: dd 1.0, M_COS_PI_1_8, M_SQRT1_2, M_COS_PI_3_8, 1.0, M_COS_PI_1_8, M_SQRT1_2, M_COS_PI_3_8
 ps_cos16_2: dd 0, M_COS_PI_3_8, M_SQRT1_2, M_COS_PI_1_8, 0, -M_COS_PI_3_8, -M_SQRT1_2, -M_COS_PI_1_8
 
 ps_root2: times 8 dd M_SQRT1_2
 ps_root2mppm: dd -M_SQRT1_2, M_SQRT1_2, M_SQRT1_2, -M_SQRT1_2, -M_SQRT1_2, M_SQRT1_2, M_SQRT1_2, -M_SQRT1_2
 ps_p1p1m1p1: dd 0, 0, 1<<31, 0, 0, 0, 1<<31, 0
 
 perm1: dd 0x00, 0x02, 0x03, 0x01, 0x03, 0x00, 0x02, 0x01
 perm2: dd 0x00, 0x01, 0x02, 0x03, 0x01, 0x00, 0x02, 0x03
 ps_p1p1m1p1root2: dd 1.0, 1.0, -1.0, 1.0, M_SQRT1_2, M_SQRT1_2, M_SQRT1_2, M_SQRT1_2
 ps_m1m1p1m1p1m1m1m1: dd 1<<31, 1<<31, 0, 1<<31, 0, 1<<31, 1<<31, 1<<31
-ps_m1m1m1m1: times 4 dd 1<<31
 ps_m1p1: dd 1<<31, 0
 
+cextern ps_neg
+
 %assign i 16
-%rep 13
+%rep 14
 cextern cos_ %+ i
 %assign i i<<1
 %endrep
 
 %if ARCH_X86_64
     %define pointer dq
 %else
     %define pointer dd
 %endif
 
 %macro IF0 1+
 %endmacro
 %macro IF1 1+
     %1
 %endmacro
 
-SECTION_TEXT
+SECTION .text
 
 %macro T2_3DNOW 4 ; z0, z1, mem0, mem1
     mova     %1, %3
     mova     %2, %1
     pfadd    %1, %4
     pfsub    %2, %4
 %endmacro
 
@@ -300,16 +300,17 @@ IF%1 mova  Z(1), m5
 %endmacro
 
 %define Z(x) [r0+mmsize*x]
 %define Z2(x) [r0+mmsize*x]
 %define ZH(x) [r0+mmsize*x+mmsize/2]
 
 INIT_YMM avx
 
+%if HAVE_AVX_EXTERNAL
 align 16
 fft8_avx:
     mova      m0, Z(0)
     mova      m1, Z(1)
     T8_AVX    m0, m1, m2, m3, m4
     mova      Z(0), m0
     mova      Z(1), m1
     ret
@@ -389,16 +390,18 @@ fft32_interleave_avx:
     vextractf128  ZH(0), m1, 0
     vextractf128   Z(1), m0, 1
     vextractf128  ZH(1), m1, 1
     add r0, mmsize*2
     sub r2d, mmsize/4
     jg .deint_loop
     ret
 
+%endif
+
 INIT_XMM sse
 
 align 16
 fft4_avx:
 fft4_sse:
     mova     m0, Z(0)
     mova     m1, Z(1)
     T4_SSE   m0, m1, m2
@@ -532,16 +535,17 @@ DEFINE_ARGS zc, w, n, o1, o3
     lea r3, [$$]
     add r2, r3
 %endif
     call r2
 %endmacro ; FFT_DISPATCH
 
 INIT_YMM avx
 
+%if HAVE_AVX_EXTERNAL
 %macro INTERL_AVX 5
     vunpckhps      %3, %2, %1
     vunpcklps      %2, %2, %1
     vextractf128   %4(%5), %2, 0
     vextractf128  %4 %+ H(%5), %3, 0
     vextractf128   %4(%5 + 1), %2, 1
     vextractf128  %4 %+ H(%5 + 1), %3, 1
 %endmacro
@@ -553,16 +557,17 @@ DECL_PASS pass_interleave_avx, PASS_BIG 
 
 cglobal fft_calc, 2,5,8
     mov     r3d, [r0 + FFTContext.nbits]
     mov     r0, r1
     mov     r1, r3
     FFT_DISPATCH _interleave %+ SUFFIX, r1
     REP_RET
 
+%endif
 
 INIT_XMM sse
 
 %macro INTERL_SSE 5
     mova     %3, %2
     unpcklps %2, %1
     unpckhps %3, %1
     mova  %4(%5), %2
@@ -676,17 +681,17 @@ cglobal imdct_calc, 3,5,3
     add     rsp, 8+32*WIN64
 %endif
     POP     r1
     POP     r3
     lea     r0, [r1 + 2*r3]
     mov     r2, r3
     sub     r3, mmsize
     neg     r2
-    mova    m2, [ps_m1m1m1m1]
+    mova    m2, [ps_neg]
 .loop:
 %if mmsize == 8
     PSWAPD  m0, [r1 + r3]
     PSWAPD  m1, [r0 + r2]
     pxor    m0, m2
 %else
     mova    m0, [r1 + r3]
     mova    m1, [r0 + r2]
@@ -746,17 +751,17 @@ DECL_PASS pass_interleave_3dnow, PASS_BI
 %if %1>=5
 %xdefine list_of_fft list_of_fft, fft16 %+ SUFFIX SECTION_REL
 %endif
 %if %1>=6
 %xdefine list_of_fft list_of_fft, fft32 %+ fullsuffix SECTION_REL
 %endif
 
 %assign n 1<<%1
-%rep 17-%1
+%rep 18-%1
 %assign n2 n/2
 %assign n4 n/4
 %xdefine list_of_fft list_of_fft, fft %+ n %+ fullsuffix SECTION_REL
 
 align 16
 fft %+ n %+ fullsuffix:
     call fft %+ n2 %+ SUFFIX
     add r0, n*4 - (n&(-2<<%1))
@@ -771,19 +776,21 @@ fft %+ n %+ fullsuffix:
 %assign n n*2
 %endrep
 %undef n
 
 align 8
 dispatch_tab %+ fullsuffix: pointer list_of_fft
 %endmacro ; DECL_FFT
 
+%if HAVE_AVX_EXTERNAL
 INIT_YMM avx
 DECL_FFT 6
 DECL_FFT 6, _interleave
+%endif
 INIT_XMM sse
 DECL_FFT 5
 DECL_FFT 5, _interleave
 %if ARCH_X86_32
 INIT_MMX 3dnow
 DECL_FFT 4
 DECL_FFT 4, _interleave
 INIT_MMX 3dnowext
@@ -987,17 +994,17 @@ cglobal imdct_half, 3,12,8; FFTContext *
 %else
     sub   r3, 4
 %endif
 %if ARCH_X86_64 || mmsize == 8
     xor   r4, r4
     sub   r4, r3
 %endif
 %if notcpuflag(3dnowext) && mmsize == 8
-    movd  m7, [ps_m1m1m1m1]
+    movd  m7, [ps_neg]
 %endif
 .pre:
 %if ARCH_X86_64 == 0
 ;unspill
 %if mmsize != 8
     xor   r4, r4
     sub   r4, r3
 %endif
@@ -1075,9 +1082,12 @@ DECL_IMDCT POSROTATESHUF
 INIT_MMX 3dnow
 DECL_IMDCT POSROTATESHUF_3DNOW
 
 INIT_MMX 3dnowext
 DECL_IMDCT POSROTATESHUF_3DNOW
 %endif
 
 INIT_YMM avx
+
+%if HAVE_AVX_EXTERNAL
 DECL_IMDCT POSROTATESHUF_AVX
+%endif
copy from media/libav/libavcodec/x86/fft.h
copy to media/ffvpx/libavcodec/x86/fft.h
--- a/media/libav/libavcodec/x86/fft.h
+++ b/media/ffvpx/libavcodec/x86/fft.h
@@ -1,23 +1,23 @@
 /*
- * 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
  */
 
 #ifndef AVCODEC_X86_FFT_H
 #define AVCODEC_X86_FFT_H
 
 #include "libavcodec/fft.h"
 
copy from media/libav/libavcodec/x86/fft_init.c
copy to media/ffvpx/libavcodec/x86/fft_init.c
--- a/media/libav/libavcodec/x86/fft_init.c
+++ b/media/ffvpx/libavcodec/x86/fft_init.c
@@ -1,57 +1,61 @@
 /*
- * 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 "config.h"
+
 #include "libavutil/attributes.h"
 #include "libavutil/cpu.h"
 #include "libavutil/x86/cpu.h"
+
 #include "fft.h"
 
 av_cold void ff_fft_init_x86(FFTContext *s)
 {
     int cpu_flags = av_get_cpu_flags();
 
+    if (s->nbits > 16)
+        return;
+
 #if ARCH_X86_32
     if (EXTERNAL_AMD3DNOW(cpu_flags)) {
-        /* 3DNow! for K6-2/3 */
         s->imdct_calc = ff_imdct_calc_3dnow;
         s->imdct_half = ff_imdct_half_3dnow;
         s->fft_calc   = ff_fft_calc_3dnow;
     }
+
     if (EXTERNAL_AMD3DNOWEXT(cpu_flags)) {
-        /* 3DNowEx for K7 */
         s->imdct_calc = ff_imdct_calc_3dnowext;
         s->imdct_half = ff_imdct_half_3dnowext;
         s->fft_calc   = ff_fft_calc_3dnowext;
     }
-#endif
+#endif /* ARCH_X86_32 */
+
     if (EXTERNAL_SSE(cpu_flags)) {
-        /* SSE for P3/P4/K8 */
         s->imdct_calc  = ff_imdct_calc_sse;
         s->imdct_half  = ff_imdct_half_sse;
         s->fft_permute = ff_fft_permute_sse;
         s->fft_calc    = ff_fft_calc_sse;
         s->fft_permutation = FF_FFT_PERM_SWAP_LSBS;
     }
-    if (EXTERNAL_AVX(cpu_flags) && s->nbits >= 5) {
-        /* AVX for SB */
+
+    if (EXTERNAL_AVX_FAST(cpu_flags) && s->nbits >= 5) {
         s->imdct_half      = ff_imdct_half_avx;
         s->fft_calc        = ff_fft_calc_avx;
         s->fft_permutation = FF_FFT_PERM_AVX;
     }
 }
--- a/media/ffvpx/libavcodec/x86/moz.build
+++ b/media/ffvpx/libavcodec/x86/moz.build
@@ -25,11 +25,17 @@ SOURCES += [
     'vp9itxfm.asm',
     'vp9itxfm_16bpp.asm',
     'vp9lpf.asm',
     'vp9lpf_16bpp.asm',
     'vp9mc.asm',
     'vp9mc_16bpp.asm',
 ]
 
+if CONFIG['MOZ_LIBAV_FFT']:
+    SOURCES += [
+        'fft.asm',
+        'fft_init.c',
+    ]
+
 FINAL_LIBRARY = 'mozavcodec'
 
 include('/media/ffvpx/ffvpxcommon.mozbuild')